$( )與` `(反引號)shell
在bash shell中,$( )與` `(反引號)都是用來作命令替換(command substitution)用的。
$ echo the last sunday is $(date -d "last sunday" +%Y-%m-%d)
獲得上一星期天的日期數組
用$( )的理由bash
1. ` `很容易與' '(單引號)搞混。有時在一些奇怪的字形顯示中,兩種符號是如出一轍的(直豎兩點)。
2. 在多層次的複合替換中,` `需要額外的跳脫(\`)處理,而$( )則比較直觀。例如:
command1 `command2 `command3` `
本來的意圖是在command2 `command3`中先將command3替換出來給command2處理,而後再將結果傳給command1 `command2 ...`來處理。
然而,真正的結果在命令行中倒是分紅了`command2`與` `兩段。
正確的輸入應該以下:
command1 `command2 \`command3\` `
換成$( )則一目瞭然:
command1 $(command2 $(command3))測試
$( )的不足命令行
` `基本上可在所有的unix shell中使用,若寫成shell script移植性比較高。而$( )並非每一種shell都能使用。unix
${ }用來做變量替換ip
通常狀況下,$var與${var}做用相同。可是用${ }會比較精確的界定變量名稱的範圍,例如:
$ A=B
$ echo $AB
本來是打算先將$A的結果替換出來,而後再補一個B字母於其後,但在命令行上,真正的結果倒是隻會替換變量名稱爲AB的值出來。
使用${ }就沒問題了:
$ echo ${A}B
BB字符串
${ }的一些特異功能it
定義一個變量:
file=/dir1/dir2/dir3/my.file.txt
能夠用${ }分別替換得到不一樣的值:
${file#*/} 拿掉第一個 / 及其左邊的字符串:dir1/dir2/dir3/my.file.txt
${file##*/} 拿掉最後一個 / 及其左邊的字符串:my.file.txt
${file#*.} 拿掉第一個 . 及其左邊的字符串:file.txt
${file##*.} 拿掉最後一個 . 及其左邊的字符串:txt
${file%/*} 拿掉最後一個 / 及其右邊的字符串:/dir1/dir2/dir3
${file%%/*} 拿掉第一個 / 及其右邊的字符串:(空值)
${file%.*} 拿掉最後一個 . 及其右邊的字符串:/dir1/dir2/dir3/my.file
${file%%.*} 拿掉第一個 . 及其右邊的字符串:/dir1/dir2/dir3/my
記憶的方法:
# 去掉左邊(鍵盤上 # 在 $ 的左邊)
% 去掉右邊(在鍵盤上 % 在 $ 的右邊)
單一符號是最小匹配,兩個符號是最大匹配。
${file:0:5} 提取最左邊的 5 個字節:/dir1
${file:5:5} 提取第 5 個字節右邊的連續 5 個字節:/dir2
也能夠對變量值裏的字符串做替換:
${file/dir/path} 將第一個 dir 替換爲 path:/path1/dir2/dir3/my.file.txt
${file//dir/path} 將所有 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} 若 $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} :若 $file 未設定或爲空值,則將 my.file.txt 輸出至 STDERR。(非空值時不做處理)
以上的理解在於,必定要分清楚 unset 與 null 及 non-null 這三種賦值狀態。
通常而言,與 null 有關,若不帶 : 的話,null 不受影響,若帶 : 則連 null 也受影響。
${#var} 可計算出變量值的長度:
${#file} 可獲得 27,/dir1/dir2/dir3/my.file.txt 恰好是 27 個字節。io
bash數組(array)處理方法
通常而言,A="a b c def"只是將 $A 替換爲一個單一的字符串,可是改成 A=(a b c def),則是將 $A 定義爲數組。
bash的數組替換方法可參考以下方法:
${A[@]} 或 ${A[*]} 獲得 a b c def(所有數組)
${A[0]} 獲得 a (第一個元素),${A[1]} 第二個...
${#A[@]} 或 ${#A[*]} 獲得 4 (數組數量)
${#A[0]} 獲得 1 (第一個元素 a 的長度),${#A[3]} 獲得 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) 的返回值 常見的用於(( ))的測試符號有如下這些: < 小於 > 大於 <= 小於或等於 >= 大於或等於 == 等於 != 不等於