在新的shell里执行程序
cd /home/lq/Server/anew-lstm_script
matlab -nodesktop -singleCompThred -r 'aStart' ,quit & SLAVE_PID=$!;
#echo "sh ./slaveRun.sh localhost 10000 localhost localhost" | xfce4-terminal
sleep 3
xfce4-terminal -x sh ./slaveRun.sh localhost 10000 localhost localhost
ls -lr反向排序结果
==============================
ls ${PATH//:/\ } | grep <searchword>
==============================
echo $RANDOM
==============================
[[ $# -ne 3 ]] && {echo "Usage: ${0##.*/} <param>"; exit 1}
==============================
awk '/'$VAR'/{print $0}' file
==============================
#得到绝对路径
bin=`dirname "$0"`
bin=`cd "$bin"; pwd`
==============================
echo $[23*34] <==> echo $((23*34))
==============================
echo $[7#23] #7是底,23是在这个底上的数字,因此最终的结果为17
==============================
echo ${!P*} #列出当前变量中,所有以P开头的变量的名称
==============================
shell的处理过程:alias la='ls -A'->{1..100}->~admin->$PATH->$(ls)->$((23*34))->rm a*o?[a-zA-Z]*
==============================
#下面这种处理方式等同于for f in "$(ls)",但是可以应对文件名中有空格的情况,而for f in "$(ls)"则不行。
[ $# -eq 0 ] && ls | while read f
do
ll-2.sh "$f"
done
==============================
可以在一行内定义一个函数,写在shell脚本里可以,还可以直接写在命令行上,比如:
root@pc1:~#testfunc(){ echo "$# parameters;echo "$@";}
而且,如果你在命令行直接这么定义的,你想查看该函数的内容时,可以用type testfunc,你会看到:
testfunc is a function
testfunc ()
{
echo "$# params";
IFS=;
echo "$*"
}
需要特别注意的是:{和echo之间的那个空格,其他地方有没有空格无所谓,但是这个空格如果没有的话,是必然会出错的;还有个地方是}前面那条命令的;必须有,否则也会有问题;最后,还需要提醒的是,如果你不是写在一行内,那么}前的;不必有,{后的空格也不必有。
===============================
对$*和$@作些说明:
其实要分四种情况:$*, $@, "$*", "$@"
对于前两种情况,都等同于$1 $2 $3 ...,如果某个参数内有了空格或者换行(不要觉得不可能,参数中是可以有换行符的,下面就有例子),比如a "b c" d,那么替换后的结果是a b c d,看上去就是四个参数了;
对于"$@",等同于"$1" "$2" "$3" ...,这下就不必担心参数中有空格或者换行符号了;
对于"$*",还要受到IFS的影响,其实是IFS中的第一个字符的影响,假定IFS中第一个字符是|的话,那么替换后的结果是"$1|$2|$3...";这里对IFS还得作下说明,如果 IFS 为空,则没有间隔空格。IFS 的默认值是空白、制表符和换行符。如果没有设置 IFS,则使用空白作为分隔符(仅对默认 IFS 而言),这里特别提到的是,如果你想把参数都串接起来,那么必须得显示设置IFS=''或者IFS=""或者IFS=即可。
下面给出一个验证上述描述的超级牛b的例子:
[ian@pinguino ~]$ type testfunc2
testfunc2 is a function
testfunc2 ()
{
echo "$# parameters";
echo Using '$*';
for p in $*;
do
echo "[$p]";
done;
echo Using '"$*"';
for p in "$*";
do
echo "[$p]";
done;
echo Using '$@';
for p in $@;
do
echo "[$p]";
done;
echo Using '"$@"';
for p in "$@";
do
echo "[$p]";
done
}
[ian@pinguino ~]$ IFS="|${IFS}" testfunc2 abc "a bc" "1 2
> 3"
3 parameters
Using $*
[abc]
[a]
[bc]
[1]
[2]
[3]
Using "$*"
[abc|a bc|1 2
3]
Using $@
[abc]
[a]
[bc]
[1]
[2]
[3]
Using "$@"
[abc]
[a bc]
[1 2
3]
看到参数中使用换行符号了吧,哈哈。
===============================
函数返回值return 0~255必须为一个整数,而且范围只能是0~255,如果大于255,那么会返回$((x%256)),而且不能返回负数,但是允许你写负数,负数会被强制转换成整数。
===============================
#!/bin/sh会提供系统默认的shell解释器,会带来一些想不到的异常情况,建议都使用#!/bin/bash,在bash中定义函数时function关键字是可选的。
===============================
#!/bin/bash
showopts () {
while getopts ":pq:" optname
do
case "$optname" in
"p")
echo "Option $optname is specified"
;;
"q")
echo "Option $optname has value $OPTARG"
;;
"?")
echo "Unknown option $OPTARG"
;;
":")
echo "No argument value for option $OPTARG"
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
return $OPTIND
}
showargs () {
for p in "$@"
do
echo "[$p]"
done
}
optinfo=$(showopts "$@")
argstart=$?
arginfo=$(showargs "${@:$argstart}")
echo "Arguments are:"
echo "$arginfo"
echo "Options are:"
echo "$optinfo"
getopts 命令使用了两个预先确定的变量。OPTIND 变量开始被设为 1。之后它包含待处理的下一个参数的索引。如果找到一个选项,则 getopts 命令返回 true,因此常见的选项处理范例使用带 case 语句的 while 循环,本例中就是如此。getopts 的第一个参数是一列要识别的选项字母,在本例中是 p 和 r。选项字母后的冒号 (:) 表示该选项需要一个值;例如,-f 选项可能用于表示文件名,tar 命令中就是如此。此例中的前导冒号告诉 getopts 保持静默(silent)并抑制正常的错误消息,因为此脚本将提供它自己的错误处理。
此例中的第二个参数 optname 是一个变量名,该变量将接收找到选项的名称。如果预期某个选项应该拥有一个值,而且目前存在该值,则会把该值放入 OPTARG 变量中。在静默模式下,可能出现以下两种错误情况。
1. 如果发现不能识别的选项,则 optname 将包含一个 ? 而 OPTARG 将包含该未知选项。
2. 如果发现一个选项需要值,但是找不到这个值,则 optname 将包含一个 : 而 OPTARG 将包含丢失参数的选项的名称。
如果不是在静默模式,则这些错误将导致一条诊断错误消息而 OPTARG 不会被设置。脚本可能在 optname 中使用 ? 或 : 值来检测错误(也可能处理错误)。
此外,getopts ":pq:" optname后面还可以配置上可选的getopts ":pq:" optname "$@"
[ian@pinguino ~]$ ./testargs.sh -p -q qoptval abc "def ghi"
Arguments are:
[abc]
[def ghi]
Options are:
Option p is specified
Option q has value qoptval
[ian@pinguino ~]$ ./testargs.sh -q qoptval -p -r abc "def ghi"
Arguments are:
[abc]
[def ghi]
Options are:
Option q has value qoptval
Option p is specified
Unknown option r
[ian@pinguino ~]$ ./testargs.sh "def ghi"
Arguments are:
[def ghi]
Options are:
===============================
父shell设置的alias是不能传到子shell中的,但是在shell script中依然可以使用alias,不过要自己手动设定了,然后还要注意在脚本中显示开启alias的使用,即 shopt -s expand_aliases;有时候会希望alias能带参数就好了,其实可以用函数代替即可,在.bashrc中增加:cpdev1(){ [ $# -eq 1 ] && scp $1 yanbin@dev1.asc.cnz.alimama.com: ; },具体啥意思,自己去琢磨吧。
===============================
while [ "${i:-1}" -lt 30 ];do a="-"${a:="-"};((i++));done && echo $a
知识点:while的条件,不新建变量还能正常使用,while是个整体,可以有返回值,可以重定向其输出
===============================
如果想实现对shell变量的二次解析,那么可以用eval完成,例如:eval cd "\"\$$#\""
===============================
for var in "$@"; <==> for var;
===============================
在shell总一般extglob都是开着的,你可以用shopt查看一下,如果没开你可以用shopt -s extglob设置一下,在这个选项打开的状态下,我们可以使用一些扩展的glob选项,在shell中是这么使用的:
?(pattern-list)Matches zero or one occurrence of the given patterns
*(pattern-list)Matches zero or more occurrences of the given patterns
+(pattern-list)Matches one or more occurrences of the given patterns
@(pattern-list)Matches one of the given patterns
!(pattern-list)Matches anything except one of the given patterns
===============================
find . -regextype posix-extended -regex '.*\.(h|cpp)'
===============================
findc(){ [ $# -eq 1 ] && compgen -c | grep --color=auto -i $1; }
===============================
在.bashrc中添加:export PS1='\[\e[1;32;40m\]\u@\h:\w\$ '达到的效果:绿色高亮显示,且折行时不会在同一行,如果去掉\[和\]则会在同一行折行。
本人目前在用的一个PS1是:export PS1='\[\e[0;35m\]>>>>[\[\e[0;33m\]\t\[\e[0;35m\]][\[\e[0;31m\]\u@\h\[\e[0;35m\]:\[\e[0;33m\]\[\e[0;34m\]\w\[\e[0;35m\]]\n\[\e[1;$((31+3*!$?))m\]\$ \[\e[0;32m\]' ,这个PS1会换行,而且新行的开始部分($或者#)会显示红色高亮(上次的命令执行失败)或者蓝色高亮(上次的命令执行正常)。
对于配色,可以参考:
}
===================================================
==============================
ls ${PATH//:/\ } | grep <searchword>
==============================
echo $RANDOM
==============================
[[ $# -ne 3 ]] && {echo "Usage: ${0##.*/} <param>"; exit 1}
==============================
awk '/'$VAR'/{print $0}' file
==============================
#得到绝对路径
bin=`dirname "$0"`
bin=`cd "$bin"; pwd`
==============================
echo $[23*34] <==> echo $((23*34))
==============================
echo $[7#23] #7是底,23是在这个底上的数字,因此最终的结果为17
==============================
echo ${!P*} #列出当前变量中,所有以P开头的变量的名称
==============================
shell的处理过程:alias la='ls -A'->{1..100}->~admin->$PATH->$(ls)->$((23*34))->rm a*o?[a-zA-Z]*
==============================
#下面这种处理方式等同于for f in "$(ls)",但是可以应对文件名中有空格的情况,而for f in "$(ls)"则不行。
[ $# -eq 0 ] && ls | while read f
do
ll-2.sh "$f"
done
==============================
可以在一行内定义一个函数,写在shell脚本里可以,还可以直接写在命令行上,比如:
root@pc1:~#testfunc(){ echo "$# parameters;echo "$@";}
而且,如果你在命令行直接这么定义的,你想查看该函数的内容时,可以用type testfunc,你会看到:
testfunc is a function
testfunc ()
{
echo "$# params";
IFS=;
echo "$*"
}
需要特别注意的是:{和echo之间的那个空格,其他地方有没有空格无所谓,但是这个空格如果没有的话,是必然会出错的;还有个地方是}前面那条命令的;必须有,否则也会有问题;最后,还需要提醒的是,如果你不是写在一行内,那么}前的;不必有,{后的空格也不必有。
===============================
对$*和$@作些说明:
其实要分四种情况:$*, $@, "$*", "$@"
对于前两种情况,都等同于$1 $2 $3 ...,如果某个参数内有了空格或者换行(不要觉得不可能,参数中是可以有换行符的,下面就有例子),比如a "b c" d,那么替换后的结果是a b c d,看上去就是四个参数了;
对于"$@",等同于"$1" "$2" "$3" ...,这下就不必担心参数中有空格或者换行符号了;
对于"$*",还要受到IFS的影响,其实是IFS中的第一个字符的影响,假定IFS中第一个字符是|的话,那么替换后的结果是"$1|$2|$3...";这里对IFS还得作下说明,如果 IFS 为空,则没有间隔空格。IFS 的默认值是空白、制表符和换行符。如果没有设置 IFS,则使用空白作为分隔符(仅对默认 IFS 而言),这里特别提到的是,如果你想把参数都串接起来,那么必须得显示设置IFS=''或者IFS=""或者IFS=即可。
下面给出一个验证上述描述的超级牛b的例子:
[ian@pinguino ~]$ type testfunc2
testfunc2 is a function
testfunc2 ()
{
echo "$# parameters";
echo Using '$*';
for p in $*;
do
echo "[$p]";
done;
echo Using '"$*"';
for p in "$*";
do
echo "[$p]";
done;
echo Using '$@';
for p in $@;
do
echo "[$p]";
done;
echo Using '"$@"';
for p in "$@";
do
echo "[$p]";
done
}
[ian@pinguino ~]$ IFS="|${IFS}" testfunc2 abc "a bc" "1 2
> 3"
3 parameters
Using $*
[abc]
[a]
[bc]
[1]
[2]
[3]
Using "$*"
[abc|a bc|1 2
3]
Using $@
[abc]
[a]
[bc]
[1]
[2]
[3]
Using "$@"
[abc]
[a bc]
[1 2
3]
看到参数中使用换行符号了吧,哈哈。
===============================
函数返回值return 0~255必须为一个整数,而且范围只能是0~255,如果大于255,那么会返回$((x%256)),而且不能返回负数,但是允许你写负数,负数会被强制转换成整数。
===============================
#!/bin/sh会提供系统默认的shell解释器,会带来一些想不到的异常情况,建议都使用#!/bin/bash,在bash中定义函数时function关键字是可选的。
===============================
#!/bin/bash
showopts () {
while getopts ":pq:" optname
do
case "$optname" in
"p")
echo "Option $optname is specified"
;;
"q")
echo "Option $optname has value $OPTARG"
;;
"?")
echo "Unknown option $OPTARG"
;;
":")
echo "No argument value for option $OPTARG"
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
return $OPTIND
}
showargs () {
for p in "$@"
do
echo "[$p]"
done
}
optinfo=$(showopts "$@")
argstart=$?
arginfo=$(showargs "${@:$argstart}")
echo "Arguments are:"
echo "$arginfo"
echo "Options are:"
echo "$optinfo"
getopts 命令使用了两个预先确定的变量。OPTIND 变量开始被设为 1。之后它包含待处理的下一个参数的索引。如果找到一个选项,则 getopts 命令返回 true,因此常见的选项处理范例使用带 case 语句的 while 循环,本例中就是如此。getopts 的第一个参数是一列要识别的选项字母,在本例中是 p 和 r。选项字母后的冒号 (:) 表示该选项需要一个值;例如,-f 选项可能用于表示文件名,tar 命令中就是如此。此例中的前导冒号告诉 getopts 保持静默(silent)并抑制正常的错误消息,因为此脚本将提供它自己的错误处理。
此例中的第二个参数 optname 是一个变量名,该变量将接收找到选项的名称。如果预期某个选项应该拥有一个值,而且目前存在该值,则会把该值放入 OPTARG 变量中。在静默模式下,可能出现以下两种错误情况。
1. 如果发现不能识别的选项,则 optname 将包含一个 ? 而 OPTARG 将包含该未知选项。
2. 如果发现一个选项需要值,但是找不到这个值,则 optname 将包含一个 : 而 OPTARG 将包含丢失参数的选项的名称。
如果不是在静默模式,则这些错误将导致一条诊断错误消息而 OPTARG 不会被设置。脚本可能在 optname 中使用 ? 或 : 值来检测错误(也可能处理错误)。
此外,getopts ":pq:" optname后面还可以配置上可选的getopts ":pq:" optname "$@"
[ian@pinguino ~]$ ./testargs.sh -p -q qoptval abc "def ghi"
Arguments are:
[abc]
[def ghi]
Options are:
Option p is specified
Option q has value qoptval
[ian@pinguino ~]$ ./testargs.sh -q qoptval -p -r abc "def ghi"
Arguments are:
[abc]
[def ghi]
Options are:
Option q has value qoptval
Option p is specified
Unknown option r
[ian@pinguino ~]$ ./testargs.sh "def ghi"
Arguments are:
[def ghi]
Options are:
===============================
父shell设置的alias是不能传到子shell中的,但是在shell script中依然可以使用alias,不过要自己手动设定了,然后还要注意在脚本中显示开启alias的使用,即 shopt -s expand_aliases;有时候会希望alias能带参数就好了,其实可以用函数代替即可,在.bashrc中增加:cpdev1(){ [ $# -eq 1 ] && scp $1 yanbin@dev1.asc.cnz.alimama.com: ; },具体啥意思,自己去琢磨吧。
===============================
while [ "${i:-1}" -lt 30 ];do a="-"${a:="-"};((i++));done && echo $a
知识点:while的条件,不新建变量还能正常使用,while是个整体,可以有返回值,可以重定向其输出
===============================
如果想实现对shell变量的二次解析,那么可以用eval完成,例如:eval cd "\"\$$#\""
===============================
for var in "$@"; <==> for var;
===============================
在shell总一般extglob都是开着的,你可以用shopt查看一下,如果没开你可以用shopt -s extglob设置一下,在这个选项打开的状态下,我们可以使用一些扩展的glob选项,在shell中是这么使用的:
?(pattern-list)Matches zero or one occurrence of the given patterns
*(pattern-list)Matches zero or more occurrences of the given patterns
+(pattern-list)Matches one or more occurrences of the given patterns
@(pattern-list)Matches one of the given patterns
!(pattern-list)Matches anything except one of the given patterns
===============================
find . -regextype posix-extended -regex '.*\.(h|cpp)'
===============================
findc(){ [ $# -eq 1 ] && compgen -c | grep --color=auto -i $1; }
===============================
在.bashrc中添加:export PS1='\[\e[1;32;40m\]\u@\h:\w\$ '达到的效果:绿色高亮显示,且折行时不会在同一行,如果去掉\[和\]则会在同一行折行。
本人目前在用的一个PS1是:export PS1='\[\e[0;35m\]>>>>[\[\e[0;33m\]\t\[\e[0;35m\]][\[\e[0;31m\]\u@\h\[\e[0;35m\]:\[\e[0;33m\]\[\e[0;34m\]\w\[\e[0;35m\]]\n\[\e[1;$((31+3*!$?))m\]\$ \[\e[0;32m\]' ,这个PS1会换行,而且新行的开始部分($或者#)会显示红色高亮(上次的命令执行失败)或者蓝色高亮(上次的命令执行正常)。
对于配色,可以参考:
}
===================================================
awk '
{
if (NF>5 || ("noresource" != $NF && "zero" != $NF && "part" != $NF && "all" != $NF)) {
print $0 > "/dev/stderr"
} else if ($4 ~ /^http/) {
print $1, (4==$2 ? "y" : "n"), $4, ($5=="all" ? "y" : "n")
} else {
print $1, (4==$2 ? "y" : "n"), "none", ($4=="all" ? "y" : "n")
}
}' $2 | awk '
BEGIN {
pv=0;
}
{
if (FILENAME==ARGV[1]) {
sitepv[$1]=++pv;
} else {
r[sitepv[$1]]=$0;
}
}
END {
for (i in r) {
print i, r[i];
}
}' $1 - | sort -n -k 1 | awk '
{
for (i=2; i<NF; ++i) {
printf "%s ", $i
}
printf "%s\n", $NF
}'
==========================================
awk -v max_qps=$max_qps -v max_qps_time="$max_qps_time" -v bad_request_num=$bad_request_num '
BEGIN {
total_request_num=0;
total_sum=0;
max_value=0;
max_value_time=0;
min_value=0;
min_value_time=0;
cur_value=0;
level8_threshold=(0 != l8 ? l8 : 3000);
level7_threshold=(0 != l7 ? l7 : 1500);
level6_threshold=(0 != l6 ? l6 : 1000);
level5_threshold=(0 != l5 ? l5 : 500);
level4_threshold=(0 != l4 ? l4 : 200);
level3_threshold=(0 != l3 ? l3 : 100);
level2_threshold=(0 != l2 ? l2 : 50);
level1_threshold=(0 != l1 ? l1 : 30);
gt_level8_threshold_num=0;
gt_level7_threshold_num=0;
gt_level6_threshold_num=0;
gt_level5_threshold_num=0;
gt_level4_threshold_num=0;
gt_level3_threshold_num=0;
gt_level2_threshold_num=0;
gt_level1_threshold_num=0;
le_level1_threshold_num=0;
}
1 == NR {
cur_value=int(substr($14,4));
max_value=min_value=cur_value;
max_value_time=min_value_time=int(substr($1,4));
++total_request_num;
total_sum += cur_value;
next;
}
{
cur_value=int(substr($14,4));
if (cur_value > max_value) {
max_value=cur_value;
max_value_time=int(substr($1,4));
} else if (cur_value < min_value) {
min_value=cur_value;
min_value_time=int(substr($1,4));
}
if (cur_value > level8_threshold) {
++gt_level8_threshold_num;
} else if (cur_value > level7_threshold) {
++gt_level7_threshold_num;
} else if (cur_value > level6_threshold) {
++gt_level6_threshold_num;
} else if (cur_value > level5_threshold) {
++gt_level5_threshold_num;
} else if (cur_value > level4_threshold) {
++gt_level4_threshold_num;
} else if (cur_value > level3_threshold) {
++gt_level3_threshold_num;
} else if (cur_value > level2_threshold) {
++gt_level2_threshold_num;
} else if (cur_value > level1_threshold) {
++gt_level1_threshold_num;
} else {
++le_level1_threshold_num;
}
++total_request_num;
total_sum += cur_value;
}
END {
gt_level7_threshold_num += gt_level8_threshold_num;
gt_level6_threshold_num += gt_level7_threshold_num;
gt_level5_threshold_num += gt_level6_threshold_num;
gt_level4_threshold_num += gt_level5_threshold_num;
gt_level3_threshold_num += gt_level4_threshold_num;
gt_level2_threshold_num += gt_level3_threshold_num;
gt_level1_threshold_num += gt_level2_threshold_num;
print total_request_num;
printf "%d(%.2f%%)\n", bad_request_num, bad_request_num * 100 / total_request_num;
printf "%d(occur at: %s)\n", max_qps, max_qps_time;
cmd="date -d @"max_value_time" +\"%F %T\""; cmd | getline max_value_time_str; close(cmd);
printf "%d ms(occur at: %s)\n", max_value, max_value_time_str;
# printf "%d ms(occur at: %s)\n", min_value, strftime("%F %T", min_value_time);
printf "%.2f ms\n", total_sum / total_request_num;
print gt_level8_threshold_num;
print gt_level7_threshold_num;
print gt_level6_threshold_num;
print gt_level5_threshold_num;
print gt_level4_threshold_num;
print gt_level3_threshold_num;
print gt_level2_threshold_num;
print gt_level1_threshold_num;
print le_level1_threshold_num;
}' $tmp_analyse_file
=================================================================
=================================================================
awk -v threshold=1000 -v debug=n '
BEGIN {
}
{
if (FILENAME==ARGV[1]) {
checked_css[$1]="y";
} else if ("y" != checked_css[$1]) {
if (n[$1] < threshold) {
css[$1, n[$1]++] = $2;
} else {
k = int((rand() * threshold) % threshold);
if("y"==debug)print "[DEBUG]over threshold:", $1, "k=", k, "old item:", css[$1, k], "new item:", $2 > "/dev/stderr";
css[$1, k] = $2;
}
} else {
if("y"==debug)print "[DEBUG]existed css:",$1 > "/dev/stderr";
}
}
END {
for (i in n) {
if (n[i] >= threshold) {
printf "%s\t", i;
for (j=0; j< threshold; ++j) {
printf "%s ", css[i, j];
}
printf "\n";
}
}
}' css_ok.txt -
========================================================================
awk 'BEGIN {
OFS=",";
array[1,2]=3; array[2,3]=5; array[3,4]=8;
for (comb in array) {
split(comb,sep,SUBSEP);
print sep[1], sep[2], array[sep[1],sep[2]];
}
}'
========================================================================
========================================================================
$ awk 'BEGIN{a["one"]=1;a["two"]=2;a["three"]; if("one2" in a)print a["one"]; for(i in a) print i, a[i]}'
three
one 1
two 2
=========================================================================
$ awk 'BEGIN{a=3;b=4; print a,b; print a, b; print a b;print a b;}'
3 4
3 4
34
34
==========================================================================
$ awk -F$'\t' 'BEGIN{OFS="\t"}{if($3 ~ /ECSHOP/)print $1,$2;}' t3.4 #否则会用空格来分隔fields,print $0不受OFS的影响
==========================================================================
==========================================================================
bash里面的大小写转换:
$ a="abCdEF"
$ echo ${a^} #process the first character
AbCdEF
$ echo ${a^^} #process all characters
ABCDEF
$ echo ${a,} #process the first character
abCdEF
$ echo ${a,,} #process all characters
abcdef
bash里的substr:
$ a="abCdEF"
$ echo ${a:1}
bCdEF
$ echo ${a:2:1}
C
bash里的数组操作:
a=() #empty array
a=(one two three) #three elements in array, with subscripts: 0 1 2
${#a[*]} #length of array
${a[*]} #all elements of array
${!a[*]} #all subscripts of array
${a[*]:2:1} #extract elements, offset index is 2, and length is 1
${a[*]:2} #extract elements, offset index is 2, and length is big enough to fetch all residue elements
${a[*]: -1} #extract last element, note that the space between : and -, by the way, ${@:3:2} will extract $3 and $4
${a[*]:2:1} #extract elements, offset index is 2, and length is 1
${a[*]:2} #extract elements, offset index is 2, and length is big enough to fetch all residue elements
${a[*]: -1} #extract last element, note that the space between : and -, by the way, ${@:3:2} will extract $3 and $4
unset a[0] #destory the element with 0 subscript
unset a[*] #destory array
bash里的associated数组(即map):
这个特性需要bash的版本>=4
declare -A a
$ a[one]=1
$ a["two"]=2
$ a[3]=three
$ echo ${!a[*]}
one two 3
bash里数组元素是否存在的检测方法:
$ ${a[two]+:} false && echo ok || echo fail #${var+XX} will be XX if var is set, or empty; so ${a[two]+:} false will be ': false'
ok
$ [[ ${a[two]+set} ]] && echo ok || echo fail #${a[two]+set} will be 'set', so [[ set ]] is true;
ok
$ ${a[2]+:} false && echo ok || echo fail #${a[2]+:} false will be ' false'
fail
bash里的复合命令(Compound Commands):
(( expression ))用于检测数值运算(ARITHMETIC EVALUATION),例如
$ (( 3+3 )) && echo ok || echo fail
ok
$ (( 3-3 )) && echo ok || echo fail
fail
也包括数值类的比较运算符:< > >= !=等
[[ expression ]]用于检测字符串相关的表达式,例如 [[ hello ]], [[ -f test.dat ]], 也可用于带BashPattern的匹配,例如[[ abc == ab* ]],或者正则字符串匹配[[ abc =~ ^ab ]]
[ expression ]不属于bash,因为[其实是一个外部命令,和ls一样
bash里忽略大小写的字符串比较:
$ shopt -s nocasematch
$ [[ aBc == abc ]] && echo ok || echo fail
ok
set -o会列出控制bash的所有选项,其实还有一些其他的选项需要通过shopt来控制,shopt会列出全部的选项
===========================================================
a2=99
a1=88
b=a2
echo ${!a*} #list all shell variables that start with a
a1 a2
echo ${!b} #this express is equal to: eval 'echo $'$b
99
===========================================================
a2=99
a1=88
b=a2
echo ${!a*} #list all shell variables that start with a
a1 a2
echo ${!b} #this express is equal to: eval 'echo $'$b
99