在bash shell中,$()
與` `(反引號)都是用來做命令替換用(command substitution)的。所謂的命令替換與我們第五章學過的變數替換差不多,都是用來重組命令列:
完成引號裡的命令列,然後將其結果替換出來,再重組命令列。
例如:
$ echo the last sunday is $(date -d "last sunday" +%y-%m-%d)
如此便可方便得到上一星期天的日期了…^_^
在操作上,用$()
或` `都無所謂,只是我」個人"比較喜歡用$()
,理由是:
` `很容易與' '(單引號)搞混亂,尤其對初學者來說。有時在一些奇怪的字形顯示中,兩種符號是一模一樣的(直豎兩點)。當然了,有經驗的朋友還是一眼就能分辯兩者。只是,若能更好的避免混亂,又何樂不為呢?^_^
在多層次的復合替換中,須要額外的跳脫(\`)處理,而
$()
則比較直觀。例如:這是錯的:
command1 `command2 `command3` `
原本的意圖是要在command2 `command3`先將command3提換出來給command2處理,然後再將結果傳給command1 `command2…`來處理。然而,真正的結果在命令列中卻是分成了`command2`與` `兩段。正確的輸入應該如下:
command1 `command2 \`command3\` `
要不然,換成$()
就沒問題了:
command1 $(command2 $(command3))
只要你喜歡,做多少層的替換都沒問題啦~~~ ^_^
不過,$()
並不是沒有斃端的…
首先,`基本上可用在全部的unix shell中使用,若寫成shell script,其移植性比較高。而
$()並不見的每一種shell都能使用,我只能跟你說,若你用
bash2`的話,肯定沒問題…^_^
接下來,再讓我們看${}
吧…它其實就是用來作變數替換用的啦。一般情況下,$var
與$
並沒有啥不一樣。但是用${}
會比較精確的界定變數名稱的範圍,比方說:
$ a=b
$ echo $ab
原本是打算先將$a的結果替換出來,然後再補乙個b字母於其後,但在命令列上,真正的結果卻是只會提換變數名稱為ab的值出來…若使用${}
就沒問題了:
$ echo
$bbb
不過,假如你只看到${}
只能用來界定變數名稱的話,那你就實在太小看bash了﹗為了完整起見,我這裡再用一些例子加以說明${}
的一些特異功能。
假設我們定義了乙個變數為:
file=/dir1/dir2/dir3/my.file.txt
我們可以用${}
分別替換獲得不同的值:
#*/} # 拿掉第一條/及其左邊的字串:dir1/dir2/dir3/my.file.txt
$ # 拿掉最後一條/及其左邊的字串:my.file.txt
$ # 拿掉第乙個.及其左邊的字串:file.txt
$ # 拿掉最後乙個.及其左邊的字串:txt
$ # 拿掉最後條/及其右邊的字串:/dir1/dir2/dir3
$ # 拿掉第一條/及其右邊的字串:(空值)
$ # 拿掉最後乙個.及其右邊的字串:/dir1/dir2/dir3/my.file
$ #拿掉第乙個.及其右邊的字串:/dir1/dir2/dir3/my
記憶的方法為:
# 是去掉左邊(在鍵盤上#在$之左邊)
% 是去掉右邊(在鍵盤上%在$之右邊)
單一符號是最小匹配,兩個符號是最大匹配。
$ # 提取第5個位元組右邊的連續5個位元組:/dir2
我們也可以對變數值裡的字串作替換:
$ # 將第乙個dir提換為path:/path1/dir2/dir3/my.file.txt
$ # 將全部dir提換為path:/path1/path2/path3/my.file.txt
利用${}
還可針對不同的變數狀態賦值(沒設定、空值、非空值)
$ # 假如$
file沒有設定,則使用my.file.txt作傳回值。(空值及非空值時不作處理)
$ # 假如$
file沒有設定或為空值,則使用my.file.txt作傳回值。(非空值時不作處理)
$ # 假如$
file設為空值或非空值,均使用my.file.txt作傳回值。(沒設定時不作處理)
$ # 若$
file為非空值,則使用my.file.txt作傳回值。(沒設定及空值時不作處理)
$ # 若$
file沒設定,則使用my.file.txt作傳回值,同時將$
file賦值為my.file.txt。(空值及非空值時不作處理)
$ # 若$
file沒設定或為空值,則使用my.file.txt作傳回值,同時將$
file賦值為my.file.txt。(非空值時不作處理)
$ # 若$
file沒設定,則將my.file.txt輸出至stderr。(空值及非空值時不作處理)
$ # 若$
file沒設定或為空值,則將my.file.txt輸出至stderr。(非空值時不作處理)
tips:
以上的理解在於,你一定要分清楚unset與null及non-null這三種賦值狀態。一般而言,: 與null有關,若不帶 : 的話,null不受影響,若帶 : 則連null也受影響。還有哦,
$
可計算出變數值的長度:
$ # 可得到27,因為/dir1/dir2/dir3/my.file.txt剛好是27個位元組…
接下來,再為大家介稍一下bash的陣列(array)處理方法。
一般而言,a="a b c def"
這樣的變數只是將$a替換為乙個單一的字串,但是改為a=(a b c def)
,則是將$a定義為陣列…bash的陣列替換方法可參考如下方法:
$或$ # 可得到a b c def(全部組數)
$ # 可得到a(第乙個組數),$則為第二個組數…
$或$ #可得到4(全部組數數量)
$ #可得到1(即第乙個組數(a)的長度),$可得到3(第四個組數(def)的長度)
a[3]=xyz # 則是將第四個組數重新定義為xyz…
能夠善用bash的$()
與${}
可大大提高及簡化shell在變數上的處理能力哦~~~ ^_^
好了,最後為大家介紹$(())
的用途吧:它是用來作整數運算的。在bash中,$(())
的整數運算符號大致有這些:+ - * /:分別為「加、減、乘、除」。%:餘數運算。& | ^!:分別為「and、or、xor、not」運算。
例:
$ a=5;b=7;c=2
$ echo $((a+b*c))
19$ echo $(((a+b)/c))
6$ echo $(((a*b)%c))
1
在$(())
中的變數名稱,可於其前面加$符號來替換,也可以不用,如:
$(($a + $b * $c))
也可得到19的結果
此外,$(())
還可作不同進製(如二進位、八進位、十六進製)作運算呢,只是,輸出結果皆為十進位制而已:
echo $((16#2a)) # 結果為42(16進製轉十進位制)
以乙個實用的例子來看看吧:假如當前的umask是022,那麼新建檔案的許可權即為:um
ask022
echo "obase=8;
you can't use 'macro parameter character #' in math mode
(umask))))" | bc
644事實上,單純用(())
也可重定義變數值,或作testing:
a=5;((a++)) #可將$a重定義為6
a=5;((a--)) 則為a=4
a=5;b=7;((a < b)) 會得到0(true)的返回值。
常見的用於(())的測試符號有如下這些:
<:小於
\>:大於
<=:小於或等於
\>=:大於或等於
==:等於
!=:不等於
不過,使用(())
作整數測試時,請不要跟[ ]
的整數測試搞混亂了。(更多的測試我將於第十章為大家介紹)怎樣?好玩吧..^_^ okay,這次暫時說這麼多…
shell學習之 與 差在哪
在解答本章題目之前,先讓我們了解乙個概念 return value 我們在 shell 下跑的每乙個 command 或 function 在結束的時候都會傳回父行程乙個值,稱為 return value 在 shell command line 中可用 這個變數得到最 新 的乙個 return v...
SHELL十三問之七 與 差在哪?
先說一下,為何要用 或 好了。qw8l8 m 1 許多時候,我們在 shell 操作上,需要在一定條件下一次執行多個命令,也就是說,要麼不執行,要麼就全執行,而不是每次依序的判斷是否要執行下乙個命令。或是,需要從一些命令執行優先次順中得到豁免,如算術的 2 3 4 那樣.這時候,我們就可引入 命令群...
SHELL十三問之十 與 差在哪?
在解答本章題目之前,先讓我們了解乙個概念 return value jdb id gy a我們在shell下跑的每乙個 command 或 function 在結束的時候都會傳回父程序乙個值,稱為 return value x9zjx x w9 q bsd愛好者樂園 ques9trm return ...