八、$(()) 与 $() 还有${} 差在哪?
8.1 $() 同 ·· 做命令替换
·· 与 ‘’ 容易混淆。
·· 在符合替换时,需要 \` 。
$() 不是在每种shell上都可以使用, ·· 在所有unix shell上都可以使用。
8.2 ${var} 与 $var 去变量值
${var} 范围更准确。
${} 更强大的功能待看。
8.3 $(()) 做整数运算
支持的整数运算符号:+、 -、 *、 /、 %、 &、 |、 ^、 !。
其中的变量可以用$取,也可以不用。
支持不同进位(二、八、十六进制)做运算、输出十进制。
8.4 (())重定义变量值或作testing
((a++))
((a<b)) //当前用的shell上不支持
九、$@ 与 $* 差在哪?
9.1 $0 是shell script名称(路径)
function是script中的script,也有positional parameter。
function中的$0是外部script名称(路径)。
9.2 $10
$10不是ten,而是one0。
取第10个参数的值:
${10}
用shift 1
9.3 $@ 与 $#
$@ 与 $# 只有在soft quote中才有差异,否则表示“全部参数”($0除外)。
#!/bin/bash my_fun() { echo "$#" } echo 'the number of parameter is "$@" is '$(my_fun "$@") echo 'the number of parameter is "$*" is '$(my_fun "$*")
执行结果:
十、&& 与 || 差在哪?
10.1 Return Value(RV)
Return Value(RV):
shell下的每一个command或function,在结束的时候都会传回给父进程一个值,称为Return Value(RV)。
在script里,用exit RV来指定其值,若没有指定,结束时最后一条命令的RV作为其值。
在function里,用return RV指定其值。
Return Value(RV)值:
Return Value(RV)取值范围0-255。
$? 取Return Value(RV)值。
Return Value(RV)用来判断进程的退出状态(exit status):
0 为“真”(true)。
非0 为假(false)。
10.2 test测试return value
test expression
[ expression ]
测试对象只支持三种:string、integer、file
expression1 -a expression2
expression1 -o expression2
10.3 && 与 ||
expression1 && expression2 :expression2 在expression1为“真”的情况下,才执行。
expression1 || expression2 :expression2 在expression1为“假”的情况下,才执行。
十一、> 与 < 差在哪?
11.1 File Descriptor (FD)
0 :Standard Input (STDIN) 默认设备:keyboard
1 :Standard Output (STDOUT) 默认设备:monitor
2 :Standard Error Output (STDERR) 默认设备:monitor
11.2 重定向输入/输出
< : 改变读进的数据信道(stdin)。
0< :0< 同 < , < 符号之前需要制定一个FD,默认为0。
<< :输入一段文本,直到读到<<后指定的内容。
> :改变输出的数据信道(stdout)。
1> :1> 同 > ,1是 > 默认的FD。
2> :改变错误的数据信道(stderr)。
>> :> 重定向输出到文件,会覆盖原来的内容。 >> 会追加输出到文件末尾。
set -o noclobber :使得 > 不能覆盖已经存在的文件。
set +o noclobber :使得 > 可以覆盖已经存在的文件。
>| :设置set -o noclobber后,使用 >| 可以临时覆盖已经存在的文件。
11.3 /dev/null
command > /dev/null
将stdout、stderr输出到/dev/null:
command > /dev/null 2>&1
command &> /dev/null
command >& /dev/null
11.4 优先级
cat < file >file 从file读入、输出到file。 结果文件的内容为空。
先准备好stdout和stderr管道,再从stdin读取。
11.5 管道pipe line
上一条命令的stdout接到下一条命令的stdin。
上一条命令的stderr不会接到下一条命令的stdin。
cmd1 | cmd2 | cmd3:
想让cmd2的内容输出到file中,并传递给cmd3
cmd1 | cmd2 > file | cmd3 < file file I/O变双倍。
cmd1 | cmd2 | tee file | cmd3 tee在不影响原本IO的情况下,将stdout复制到file中去。
十二、你要 if 还是 case 呢?
12.1 if
#!/bin/bash if [ $1 -lt $2 ] then echo "$1 is less than $2" elif [ $1 -eq $2 ] then echo "$1 is equal $2" else echo "$1 is great than $2" fi
输出结果:
12. case
#!/bin/bash case $1 in [Yy]|[Yy][Ee][Ss]) echo "yes" ;; [Nn]|[Nn][Oo]) echo "no" ;; *) echo "other" ;; esac
十三、for what? while 与 until 差在哪?
13.1 for
#!/bin/bash for m in a b c do for((n=1;n<5;n++)) do echo "m,n is: $m $n" if [ $n -gt 2 ] then continue 2 fi if [ $m = c ] then break 2 fi done done
输出结果:
13.2 while
while循环:
#!/bin/bash num=1 while [ $num -lt 10 ] do echo "\$num is $num" num=$(($num + 1)) done
死循环:
#!/bin/bash while :; do echo "hello" done
13.3 until
until循环:
#!/bin/bash num=1 until [ $num -ge 10 ] do echo "\$num is $num" ((num++)) done
13.4 break、continue
break n
“从里往外”打断第n个循环。(n 默认值为1 )
continue n
“从里往外”继续第n个循环。(n 默认值为1 )
break 结束 loop
return 结束 function
exit 结束 script/shell
十四、[^ ] 与 [! ] 差在哪
[^ ] 与 [! ] 的区别,就是Wildcard 与 Regular Expression 的区别。
command line format : command_name options arguments
变量替换: 先替换,再重组 command line
14.1 wildcard
wildcard是一种命令行的路径扩展(path expansion)功能。
只作用在command line的argument中的path之上。
常见的wildcard:
* :匹配0或多个字符。
?:匹配任意一个字符。
[list] :匹配list中的任意一个字符。
[!list] :匹配不在list中的任意一个字符。
{string1, string2, ...} :匹配string1、sting2、...中的一个字符串。
string也可以ASCII的起止范围,如a-d。
注意:
[! ] 中的 !只有放在第一位时,才有排除功能。
[ - ] - 左右两边均有字符时,才表示一段范围,否则做“-”(减号)处理。
以 * 或 ? 开始的wildcard不能匹配隐藏文件。
14.2 Regular express(RE)
Regular express(RE)只用于“字符串处理”的程序之中,与路径名称一点关系都没有。
Regular express(RE)所处理的字符串是指纯文档或透过stdin读进的内容。
不少shell meta与RE的meta是冲突的:
shell command line中有meta和literal, RE中也有meta和literal (RE中用escape(\)关闭meta)。
不少shell meta与RE的meta是冲突的。
例如:* 在RE里是一个modifier(后述),在command line上是一个wildcard。
解决办法:用shell quoting,关掉 shell meta。
锚点(anchor):
^ :表示句首
$ :表示句尾
\< :表示词首
\> :表示词尾
修饰字符(modifier):
* :出现0次或多次。
? :出现0次或1次。
+ :出现1次或多次。
{n} :出现n次。
{n, m} :出现n到m次。
14.3 grep、egrep、fgrep区别
grep:
egrep:
grep下不支持 ? 与 + 这两种modifier,但egrep可以。
grep不支持a|b或(abc|xyz)这类“或一”比对,但egrep可以。
grep在处理{n, m}时,需用\{ 与 \} 处理,但egrep不需。
fgrep:
不做RE处理,表达式仅做一般字符串处理,所有meta均失去功能。