常州外貿(mào)網(wǎng)站建設(shè)公司網(wǎng)絡(luò)科技有限公司
最近學(xué)習(xí)Linux Shell編程,對(duì)?() (()) [] [[]]等符號(hào)的用法還是有點(diǎn)分不太清楚,于是決定再梳理一下。今天先整理?() $() (()) 的用法。
1 單小括號(hào)()
1.1 子shell(命令組)
括號(hào)中的命令將會(huì)新開一個(gè)子shell順序執(zhí)行,所以括號(hào)中的變量不能夠被腳本余下的部分使用。括號(hào)中多個(gè)命令之間用分號(hào)隔開,最后一個(gè)命令可以沒有分號(hào),各命令和括號(hào)之間不必有空格。
1.1.1 bash中
$ bash
[csdn ~]$ i=1; echo $i;(let i+=5; echo $i); echo $i
1
6
1
[csdn ~]$?
?
1.1.2 在zsh中
# csdn @ edu in ~ [16:08:09]?
$ i=1; echo $i;(let i+=5; echo $i); echo $i
1
6
1
在上面的實(shí)例中,執(zhí)行命令i=1; echo $i?時(shí)變量i初始為1
執(zhí)行命令(let i+=5; echo $i);時(shí),會(huì)創(chuàng)建一個(gè)子shell來執(zhí)行,其中變量值i變?yōu)?
最后執(zhí)行命令echo $i,母shell中的變量i的值并沒有繼承子shell中的變化,仍然為1
1.2 用于定義并初始化數(shù)組
如:
a=(1 2 3 4 a b c d) ? ? ???
定義了數(shù)組?a并初始化其中的元素值。
1.3 用于條件判斷
1.3.1 bash中
[csdn ~]$ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
bash: syntax error near unexpected token `;'
[csdn ~]$ i=1;while (test $i -lt 10); do echo $i; let i++; done
1
2
3
4
5
6
7
8
9
1.3.2 在zsh中
# csdn @ edu in ~ [19:00:25] C:1
$ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
i>=0# csdn @ edu in ~ [19:00:46]?
$ i=1;while (test $i -lt 10); do echo $i; let i++; done ? ? ? ? ?
1
2
3
4
5
6
7
8
9# csdn @ edu in ~ [19:00:52]?
$ i=1;while (test $i < 10); do echo $i; let i++; done
zsh: no such file or directory: 10# csdn @ edu in ~ [19:02:11]?
$ i=1;while (test $i != 10); do echo $i; let i++; done
1
2
3
4
5
6
7
8
9
2 $():命令替換
與` `(反引號(hào))相似,都是用來作命令替換的,即,先完成()(小拓號(hào))或` `(反引號(hào))里的命令行,然后將其標(biāo)準(zhǔn)輸出結(jié)果替換出來。
2.1 在bash中
[csdn ~]$ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
/home/csdn \\n path: / \\n /home/csdn
[csdn ~]$ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo `pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd`
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo $(pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd)
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo $(pwd;echo -e "\\n"; (cd /;echo path:;pwd); echo -e "\\n"; pwd)
/home/csdn path: / /home/csdn
[csdn ~]$?
在上面的實(shí)例中,我們先執(zhí)行pwd命令顯示當(dāng)前目錄路徑:/home/csdn
然后執(zhí)行命令echo '\\n'來換行
接著打開一個(gè)子shell執(zhí)行命令:?(cd /;echo path:;pwd);?其中命令cd /將當(dāng)前目錄改為/,再用pwd顯示當(dāng)前目錄路徑:/
然后我們執(zhí)行命令echo '\\n'來換行
最后再用pwd顯示當(dāng)前目錄路徑:/home/csdn
但是echo '\\n'命令沒有實(shí)現(xiàn)換行,用了-e選項(xiàng)還是不行。
2.2 在zsh中
# csdn @ edu in ~ [17:21:47]?
$ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
/home/csdn?
?path: /?
?/home/csdn# csdn @ edu in ~ [17:22:07]?
$ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
/home/csdn path: / /home/csdn
同樣的命令,在zsh中執(zhí)行正確,換行也生效了。
注:有些shell不支持這種使用方法,如tcsh。
3 雙小括號(hào)(()):整數(shù)運(yùn)算、進(jìn)制轉(zhuǎn)換
3.1 整數(shù)運(yùn)算、比較
3.1.1 在bash中
# csdn @ edu in ~ [22:20:39]?
$ bash
[csdn ~]$ echo $((3+5))
8
[csdn ~]$ echo $((8 > 6))
1
[csdn ~]$ echo $((5+3 > 6))
1
[csdn ~]$?
3.1.2 在zsh中
[csdn ~]$ zsh
# csdn @ edu in ~ [22:19:50]?
$ echo $((3+5)) ? ? ?
8# csdn @ edu in ~ [22:20:11]?
$ echo $((8 > 6))
1# csdn @ edu in ~ [22:20:27]?
$ echo $((3+5 > 6))
1# csdn @ edu in ~ [22:20:39]?
$?
3.2 進(jìn)制轉(zhuǎn)換
$(( ))可以將其他進(jìn)制轉(zhuǎn)成十進(jìn)制數(shù)顯示出來。用法如下:
$((N#x))
其中,N為進(jìn)制,x為該進(jìn)制下某個(gè)數(shù)值,命令執(zhí)行后可以得到該進(jìn)制數(shù)轉(zhuǎn)成十進(jìn)制后的值。
?
3.2.1 在bash中
$ bash
[csdn ~]$ echo $((2#1000))
8
[csdn ~]$ echo $((8#1000))
512
[csdn ~]$ echo $((16#1000))
4096
[csdn ~]$ echo $((16#1000 - 1000))
3096
[csdn ~]$ echo $((16#1000 - 1000 ?> 2000))?
bash: 16#1000 - 1000 ?> 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
[csdn ~]$ echo $(((16#1000 - 1000) ?> 2000))?
bash: (16#1000 - 1000) ?> 2000: syntax error: operand expected (error token is " > 2000")
[csdn ~]$ echo $(( $(16#1000 - 1000) ?> 2000))?
bash: 16#1000: command not found
bash: ?> 2000: syntax error: operand expected (error token is " > 2000")
[csdn ~]$ i=1000; $((16#$i-1000 > 2000))
bash: 1: command not found
[csdn ~]$ i=1000; $((16#${i}-1000 > 2000))
bash: 1: command not found[csdn ~]$ echo $((16#1000 ?> 2000))?
bash: 16#1000 ?> 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
[csdn ~]$?
在bash中,可以順利完成進(jìn)制轉(zhuǎn)換,進(jìn)制轉(zhuǎn)換和運(yùn)算,但進(jìn)制轉(zhuǎn)換和比較不成功。
3.2.2 在zsh中
# csdn @ edu in ~ [15:08:45] C:1
$ echo $((2#1000))
8# csdn @ edu in ~ [15:08:52]?
$ echo $((8#1000))
512# csdn @ edu in ~ [15:09:00]?
$ echo $((16#1000))
4096# csdn @ edu in ~ [15:09:06]?
$ echo $((16#1000 - 1000))
3096# csdn @ edu in ~ [15:11:31]?
$ echo $((16#1000 - 1000 ?> 2000))?
1
在zsh中,可以順利完成進(jìn)制轉(zhuǎn)換,進(jìn)制轉(zhuǎn)換和運(yùn)算,進(jìn)制轉(zhuǎn)換、運(yùn)算和比較。?
在這點(diǎn)上,zsh表現(xiàn)優(yōu)于bash。
3.3 在(())中使用變量
3.3.1 在bash中
# csdn @ edu in ~ [15:24:06]?
$ bash
[csdn ~]$ i=5;echo $((i+9))
14
[csdn ~]$ i=12; echo $((8#i+9))
bash: 8#i: value too great for base (error token is "8#i")
[csdn ~]$ i=12; echo $((8#${i}+9))
19
[csdn ~]$ i=12; echo $((8#$i+9))
19
[csdn ~]$ i=12; echo $((8#$i+9 > 10))
1
[csdn ~]$?
3.3.2 在zsh中
?csdn @ edu in ~ [15:22:38]?
$ i=5; echo $((i+9))
14# csdn @ edu in ~ [15:23:00]?
$ i=12; echo $((8#i+9))
zsh: bad math expression: operator expected at `i+9'# csdn @ edu in ~ [15:23:23] C:1
$ i=12; echo $((8#${i}+9))?
19# csdn @ edu in ~ [15:23:34]?
$ i=12; echo $((8#${i}+9 > 10))
1
在bash和zsh中,在 (( )) 中使用變量一般不需要加上$前綴,(( )) 會(huì)自動(dòng)解析變量名,這使得代碼更加簡(jiǎn)潔,也符合程序員的書寫習(xí)慣。
但也有例外。比如:
i=12; echo $((8#i+9))
bash和zsh都無法識(shí)其中的變量i,于是我們要?用 $i?或 ${i}把變量i標(biāo)記出來。
3.4 總結(jié)
shell類型 | 整數(shù)運(yùn)算 | 比較 | 算術(shù)&比較 | 進(jìn)制轉(zhuǎn)換 | 進(jìn)制轉(zhuǎn)換&算術(shù)&比較 |
bash | √ | √ | √ | √ | × |
zsh | √ | √ | √ | √ | √ |
3.5 注意
(( )) 只能用于整數(shù)算,不能用于小數(shù)(浮點(diǎn)數(shù))或者字符串。要進(jìn)行小數(shù)運(yùn)算,可以使用 bc 命令。