與 還有有 差在哪???

2021-08-03 23:48:38 字數 4628 閱讀 5536

在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 ...