shell中 與 及 的區別

2021-07-10 03:38:40 字數 3572 閱讀 7320

$( )與` `(反引號)

在bash shell中,$( )與` `(反引號)都是用來做命令替換(command substitution)用的。

$ echo the last sunday is $(date -d "last sunday" +%y-%m-%d)

得到上一星期天的日期

用$( )的理由

1. ` `很容易與' '(單引號)搞混。有時在一些奇怪的字形顯示中,兩種符號是一模一樣的(直豎兩點)。

2. 在多層次的復合替換中,` `須要額外的跳脫(\`)處理,而$( )則比較直觀。例如:

command1 `command2 `command3` `

原本的意圖是在command2 `command3`中先將command3替換出來給command2處理,然後再將結果傳給command1 `command2 ...`來處理。

然而,真正的結果在命令列中卻是分成了`command2`與` `兩段。

正確的輸入應該如下:

command1 `command2 \`command3\` `

換成$( )則一目了然:

command1 $(command2 $(command3))

$( )的不足

` `基本上可在全部的unix shell中使用,若寫成shell script移植性比較高。而$( )並不是每一種shell都能使用。

$用來作變數替換

一般情況下,$var與$作用相同。但是用$會比較精確的界定變數名稱的範圍,例如:

$ a=b

$ echo $ab

原本是打算先將$a的結果替換出來,然後再補乙個b字母於其後,但在命令列上,真正的結果卻是只會替換變數名稱為ab的值出來。

使用$就沒問題了:

$ echo $b

bb$的一些特異功能

定義乙個變數:

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 個位元組:/dir1

$ 提取第 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。(非空值時不作處理)

以上的理解在於,一定要分清楚 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 中,$(( ))的整數運算符號大致有這些:

+ - * / 加、減、乘、除

% 餘數運算

& | ^ ! 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,新建檔案的許可權為:

$ umask 022

$ echo "obase=8; $(( 8#666 & (8#777 ^ 8#$(umask)) ))" | bc

644事實上,單純用(( ))也可以重定義變數值,或作testing:

a=5; ((a++)) 將 $a 重定義為 6

a=5; ((a–)) a=4

a=5; b=7; ((a < b)) 會得到 0 (true) 的返回值

常見的用於(( ))的測試符號有以下這些:

< 小於

> 大於

<= 小於或等於

>= 大於或等於

== 等於

!= 不等於

shell中 與 的區別

命令替換 在bash中,與 反引號 都是用來作命令替換的。命令替換與變數替換差不多,都是用來重組命令列的,先完成引號裡的命令列,然後將其結果替換出來,再重組成新的命令列。exp 1 echo today is date y m d today is 2014 07 01 與 在操作上,這兩者都是達到...

shell 中 與 的區別

在shell中 為建立 echo hello shell out.txt 為追加 echo hello shell out.txt 當out.txt 文字不存在時,與 都會預設建立out.txt文字,並將hello shell 字串儲存到out.txt中 當out.txt文字存在時,會將out.tx...

shell中 與 的區別

是符合posix標準的測試語句,相容性更強,幾乎可以執行在所有的shell直譯器中 僅可執行在特定的幾個shell直譯器中 如bash等 進行比較前先設定lang c,在排序時使用ascii碼順序 數字的ascii碼應該小於大寫字母,使用 的結果是正確的 不支援 a 中表示變數name是否以字母d開...