| 我的GitHub | 我的博客 | 我的微信 | 我的郵箱 |
|---|---|---|---|
| baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目錄
Bash 教程
本文改編自 網道的 Bash 教程,主要為了精簡大量本人不感興趣的內容。
Bash 字符串
字符串的表示
單引號和雙引號
shell 中的字符串可以用單引號,也可以用雙引號,也可以不用引號。
單引號中的特殊字符(包括反斜杠)都會變為普通字符,雙引號里面的大部分特殊字符會變成普通字符(除了后面提到的三個特殊字符)。
echo 白 "白" '白' # 【白 白 白】字符串可以使用雙引號、單引號包裹,也可以省略引號
# 引號嵌套
echo '單中有"雙' # 【單中有"雙】,單引號中的雙引號不需要轉義---單引號中的特殊字符都會變為普通字符
echo "雙中有'單" # 【雙中有'單】,雙引號中的單引號不需要轉義
echo 需\"要\'轉義 # 【需"要'轉義】,沒有引號時,雙引號、單引號都需要轉義
echo "需要\"轉義" # 【需要"轉義】,雙引號中的雙引號需要轉義
echo "不"需要"轉義" # 【不需要轉義】,雙引號中可成對出現一對雙引號,作為字符串拼接使用(其實可認為是兩個字符串)
# 單引號中的單引號
echo it's # 【(等待輸入)】,不正確,等待輸入配對的單引號
echo 'it\'s' # 【(等待輸入)】,單引號中的特殊字符都會變為普通字符,所以單引號中不能使用反斜杠轉義
echo $'it\'s' # 【it's】,正確,不建議
echo 'it''s' # 【its】,正確,單引號中可成對出現一對單引號,作為字符串拼接使用(其實可認為是兩個字符串)
轉義字符 \
echo '\' # 【\】,單引號中的特殊字符都會變為普通字符,包括反斜杠
echo \ # 【(等待輸入)】,按回車后,命令行不會立即執行,而是等待用戶繼續輸入,直到下個回車后才會一並執行
echo \\ # 【\】,連續使用兩個反斜線,可對反斜線自身轉義
echo "\\" # 【\】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo "\" # 【"】,轉義后,由於缺少配對的【"】,所以會等待用戶輸入匹配的【"】后才會執行
不可打印字符 \n\r\t\b\a
【\a】響鈴、【\b】退格、【\n】換行、【\r】回車、【\t】制表
echo "a\a\b\n\r\tb" # 【a\a\b\n\r\tb】,默認情況下,雙引號和單引號會讓不可打印字符變成普通字符
echo -e "a\tb" # 【a b】,放在雙引號和單引號里面,並使用【-e】參數,會解釋里面的不可打印字符
echo a\b\tc\\td # 【abtc\td】,不加雙引號和單引號時,單獨的反斜杠會被忽略,不可打印字符會變成普通字符
echo -e a\b\tc\\td # 【abtc d】,加參數【-e】時,單獨的反斜杠會被忽略,但不可打印字符也會被解釋
echo a\ # 【(等待輸入)】,按回車后,命令行不會立即執行,而是等待用戶繼續輸入,直到下個回車后才會一並執行
echo "a\ # 【(等待輸入)】,同上,等待用戶繼續輸入,直到下個【"+回車】后才會一並執行
echo 'a\ # 【(等待輸入)】,同上,注意,行尾的【\】不會被替換為換行或空格,而是會直接合並兩行的內容
pwd;\ # 【(等待輸入)】,行尾的反斜杠可以使換行符 \n 變成普通字符,從而可以將一行命令寫成多行
ll
模式擴展字符 ~?*[]{}()$
a=白
echo $a "$a" # 【白 白】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo \$a "\$a" # 【$a $a】,在特殊字符前面加上反斜杠進行轉義(escape)后,可以變為普通字符
echo '$a \$a' # 【$a \$a】,單引號中的特殊字符都會變為普通字符
echo \~ \? \* # 【~ ? *】,不加反斜杠進行轉義時,模式擴展字符會自動擴展(擴展失敗時,會變為普通字符)
雙引號中的三個特殊字符
單引號中的特殊字符(包括反斜杠)都會變為普通字符,雙引號里面的大部分特殊字符會變成普通字符,但是以下三個特殊字符除外:
- 美元符號
$:用來引用變量 - 反斜杠
\:用來轉義 - 反引號
`:執行子命令
echo `pwd` # 【/home/bqt】,使用反引號可以顯示命令執行的結果
echo "`pwd`" # 【/home/bqt】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo "hello # 換行符在雙引號之中不再被解釋為命令的結束,所以可以利用雙引號在命令行輸入多行文本
ls "b qt.txt" # 文件名包含空格時,必須將文件名放在雙引號或單引號里面
echo "a b" # 雙引號會原樣保存多余的空格
echo "$(cal)" # 雙引號會保存命令原始的輸出格式,不加雙引號時會單行輸出
使用 Here 文檔輸入多行字符串
Here 文檔(here document)是一種輸入多行字符串的方法,格式如下:
command << token # 開始標記,由兩個小於號 + Here 文檔的名稱組成,名稱可以隨意取
text # 字符串的內容
token # 結束標記,單獨一行頂格寫的 Here 文檔名稱
- Here 文檔的本質是重定向,它將字符串重定向輸出給某個命令,相當於
echo text | command - Here 字符串只適合那些可以接受
標准輸入作為參數的命令,對於 echo 等其他命令無效 - Here 文檔不能作為變量的值,只能用於命令的參數
- Here 文檔內部會發生變量替換,並且雙引號和單引號都變成了普通字符
- Here 文檔內部支持反斜杠轉義,但是不支持通配符擴展
a=白
cat << bqt # Here 文檔內部會發生變量替換,並且雙引號和單引號都變成了普通字符
$a "$a" '$a' # 【白 "白" '白'】
bqt
cat << 'bqt' # 把 Here 文檔的開始標記放在單引號之中,可以避免變量替換
$a "$a" '$a' # 【$a "$a" '$a'】
bqt
使用 Here 字符串模擬標准輸入
Here 文檔還有一個變體,叫做 Here 字符串(Here string),使用三個小於號(<<<)表示。它的作用是將字符串通過標准輸入,傳遞給命令。
cat <<< 'aaa' # 等同於【echo 'aaa' | cat】
有些命令直接接受給定的參數,與通過標准輸入接受參數,結果是不一樣的。例如cat命令,只能接受標准輸入作為參數,如果直接將字符串放在命令后面,會被當作文件名,即cat aaa里面的aaa會被解釋成文件名。這時就可以用 Here 字符串,將字符串aaa通過標准輸入傳給cat命令。
提取子字符串
${varname:offset}:從第 offset 個字符開始(從0開始計算),截取到字符串的結尾${varname:offset:length}:從第 offset 個字符開始(從0開始計算),截取 length 個字符${varname:offset:-length}:從第 offset 個字符開始(從0開始計算),排除末尾的 length 個字符${varname: -offset}:從倒數第 offset 個字符開始(從1開始計算),截取到字符串的結尾${varname: -offset:length}:從倒數第 offset 個字符開始(從1開始計算),截取 length 個字符${varname: -offset:-length}:從倒數第 offset 個字符開始(從1開始計算),排除末尾的 length 個字符
注意事項:
- 不能直接操作字符串,只能通過
變量名來讀取字符串 - 不會改變原始字符串
- 負的
-offset前面必須有一個空格, 以防與${variable:-word}的設置變量默認值語法混淆
bqt="baiqiantao"
echo ${#bqt} # 【10】,字符串的長度
echo ${bqt:3} # 【qiantao】,從第 3 個字符開始(從 0 開始計算),截取到字符串的結尾
echo ${bqt:3:4} # 【qian】,從第 3 個字符開始(從 0 開始計算),截取 4 個字符
echo ${bqt:3:-1} # 【qianta】,從第 3 個字符開始(從 0 開始計算),排除末尾的 1 個字符
echo ${bqt: -3} # 【tao】,從倒數第 3 個字符開始(從 1 開始計算),截取到字符串的結尾
echo ${bqt: -3:2} # 【ta】,從倒數第 3 個字符開始(從 1 開始計算),截取 2 個字符
echo ${bqt: -3:-1} # 【ta】,從倒數第 3 個字符開始(從 1 開始計算),排除末尾的 1 個字符
# 越界情況
echo ${bqt:11:-1} # 【空字符串】,如果 offset 越界了,那么直接返回空字符串,后面的 length 無效
echo ${bqt:10:-1} # 【報錯】,如果 offset 沒有越界,那么排除的長度 length 不能超過子字符串的長度
echo ${bqt: -3:-4} # 【報錯】,如果 offset 沒有越界,那么排除的長度 length 不能超過子字符串的長度
echo ${bqt:3:40}-${bqt: -3:40} # 【qiantao-tao】,如果 offset 沒有越界,那么截取的長度沒有大小限制
# 以下全部返回空字符串
echo ${bqt:30}-${bqt:30:4}-${bqt:30:-4}-${bqt:30:40}-${bqt:30:-40}
echo ${bqt: -30}-${bqt: -30:4}-${bqt: -30:-4}-${bqt: -30:40}-${bqt: -30:-40}
替換匹配的字符串
如果模式匹配成功,就刪除匹配的部分,返回剩下的部分(原始變量不會發生變化)。如果匹配不成功,則返回原始字符串。
字符串頭部的模式匹配
檢查 pattern 是否匹配變量 var 的開頭
${var#pattern}:如果匹配,則刪除最短匹配(又稱非貪婪匹配)的部分,返回剩余部分${var##pattern}:如果匹配,則刪除最長匹配(又稱貪婪匹配)的部分,返回剩余部分${var/#pattern/string}:如果匹配,則將匹配的部分替換成 string(可為空) 后返回
path=/home/bqt/test/hello
echo ${path#/*/} # 【bqt/test/hello】,匹配模式【/*/】的最短匹配是【/home/】
echo ${path##/*/} # 【hello】,匹配模式【/*/】的最長匹配是【/home/bqt/test/】
echo ${path#*/} # 【home/bqt/test/hello】,匹配模式【*/】的最短匹配是【/】
echo ${path##*/} # 【hello】,匹配模式【*/】的最長匹配是【/home/bqt/test/】,此模式可用來返回文件名
foo=home/bqt/test/hello
echo ${foo/#home/xxx} # 【xxx/bqt/test/hello】,將【home】替換為【xxx】
echo ${foo/#home*test/xxx} # 【xxx/hello】,將【home/bqt/test】替換為【xxx】
echo ${foo/#home*test//xxx} # 【/xxx/hello】,將【home/bqt/test】替換為【/xxx】
echo ${foo/#home*test\//xxx} # 【xxxhello】,將【home/bqt/test/】替換為【xxx】
echo ${foo/##*/xxx} # 【home/bqt/test/hello】,不支持【##】,匹配模式會識別為【#*】
字符串尾部的模式匹配
檢查 pattern 是否匹配變量 var 的尾部
${var%pattern}:如果匹配,則刪除最短匹配(又稱非貪婪匹配)的部分,返回剩余部分${var%%pattern}:如果匹配,則刪除最長匹配(又稱貪婪匹配)的部分,返回剩余部分${var/%pattern/string}:如果匹配,則將匹配的部分替換成 string(可為空) 后返回
path=/home/bqt/test/hello
echo ${path%t*} # 【/home/bqt/tes】
echo ${path%%t*} # 【/home/bq】
echo ${path%/*} # 【/home/bqt/test】,此模式可刪除路徑的文件名部分,只留下目錄部分
echo ${path/%hello/xxx} # 【/home/bqt/test/xxx】,將【hello】替換為【xxx】
echo ${path/%b*hello/xxx} # 【/home/xxx】,將【bqt/test/hello】替換為【xxx】
echo ${path/%t/*hello/xxx} # 【/home/bqt/test/hello】,因為不匹配結尾,所以返回原始字符串
echo ${path/%t\/*hello/xxx} # 【/home/bqxxx】,將【t/test/hello】替換為【xxx】,貪婪匹配
echo ${path/%%*/xxx} # 【home/bqt/test/hello】,不支持【%%】,匹配模式會識別為【%*】
任意位置的模式匹配
檢查 pattern 是否匹配變量 var 的一部分
${var/pattern/string}:如果匹配,則將最長匹配的那部分替換成 string 后返回,僅替換第一個匹配${var//pattern/string}:如果匹配,則將最長匹配的那部分替換成 string 后返回,所有匹配都替換- 如果省略了
string部分,相當於匹配的部分替換成空字符串,即刪除匹配的部分
path=home/bqt/test/hello
echo ${path/??t/xxx} # 【home/xxx/test/hello】僅替換第一個匹配
echo ${path//??t/xxx} # 【home/xxx/txxx/hello】所有匹配都替換
echo ${path/\/*t/xxx} # 【homexxx/hello】最長匹配
echo ${path//\/*t/xxx} # 【homexxx/hello】最長匹配
echo ${path//??t/} # 【home//t/hello】刪除所有匹配的部分
echo -e ${PATH//:/"\n"} # 將環境變量 PATH 中的所有分隔符,由【:】替換成【\n】,並解釋為換行符
計算字符位置
expr index "$var" sub:返回字符串 sub 中的所有字符,在變量 var 中的最小位置
bqt="baiqiantao"
echo `expr index "$bqt" a` #【2】,返回字符 a 在變量中的最小位置
echo `expr index "$bqt" qa` #【2】,返回字符 q 或 a 在變量中的最小位置
echo `expr index "$bqt" xy` #【0】,如果所有字符都不存在,則返回 0
echo `expr index "$bqt" xq` #【4】,忽略不存在的字符 x,返回字符 q 在變量中的最小位置
其他簡單操作
${#varname}:字符串的長度${varname^^}:轉為大寫${varname,,}:轉為小寫
bqt="baiQianTao"
echo ${#bqt} # 【10】,字符串的長度
echo $#bqt # 【0bqt】,大括號是必需的,否則會將 $# 理解成腳本的參數個數,將變量名理解成文本
echo ${bqt^^} # 【BAIQIANTAO】,轉為大寫
echo ${bqt,,} # 【baiqiantao】,轉為小寫
Bash 的模式擴展
Shell 接收到用戶輸入的命令以后,會根據空格將用戶的輸入,拆分成一個個詞元(token)。然后,Shell 會擴展詞元里面的特殊字符(~、?、*、[]、{}、$),擴展完成后才會調用相應的命令。這種特殊字符的擴展,稱為模式擴展(globbing)。
Bash 是先進行擴展,再執行命令。擴展的結果是由 Bash 負責的,與所要執行的命令無關。命令本身並不存在參數擴展,收到什么參數就原樣執行。
模塊擴展的英文單詞是
globbing,這個詞來自於早期的 Unix 系統有一個/etc/glob文件,保存擴展的模板。后來 Bash 內置了這個功能,但是這個名字就保留了下來。
模式擴展與正則表達式的關系是:模式擴展的出現早於正則表達式,可以看作是原始的、早期的、低配版正則表達式,它的功能沒有正則那么強大靈活,但是優點是簡單和方便。
set -f # 【set -o noglob】關閉擴展
set +f # 【set +o noglob】打開擴展
文件名擴展
文件名擴展字符只有 文件存在 的前提下才會擴展,如果不存在可匹配的文件名,就會原樣輸出。
用戶主目錄 ~
波浪線~會擴展成當前用戶的主目錄。
echo ~ # 【/home/bqt】波浪線 ~ 會擴展成當前用戶的主目錄
echo ~/foo # 【/home/bqt/foo】主目錄的某個子目錄
echo ~root # 【/root】用戶 root 的主目錄
echo ~foo # 【~foo】如果用戶名 foo 不存在,就會原樣輸出
echo ~+ # 擴展成當前所在的目錄,等同於【pwd】命令
單個字符 ?
字符?代表文件路徑里面的任意單個字符,不包括空字符。
ls ?.txt # 【a.txt】字符 ? 代表文件路徑里面的任意單個字符,不包括空字符
ls ??.txt # 【ab.txt】如果匹配多個字符,就需要多個 ? 連用
echo ?.bqt # 【?.bqt】如果不存在可匹配的文件名,就會原樣輸出
任意字符 *
字符*代表文件路徑里面的任意數量的任意字符,包括零個字符。*不會匹配以.開頭的隱藏文件
echo *.txt # 【a.txt ab.txt】字符 * 代表文件路徑里面的任意數量的任意字符,包括零個字符
echo * # 輸出當前目錄所有文件,不包括以 . 開頭的隱藏文件,不包括子目錄中的文件
echo *.bqt # 【*.bqt】如果不存在可匹配的文件名,就會原樣輸出
echo .* # 輸出當前目錄所有隱藏文件(即以 . 開頭的文件)
echo .[!.]* # 輸出當前目錄所有隱藏文件,同時排除 .(當前目錄)和 ..(上級目錄)這兩個隱藏文件
*只匹配當前目錄,不會匹配子目錄
echo */ # 輸出當前目錄所有子目錄
echo */* # 輸出當前目錄所有子目錄中的所有文件
echo */*/ # 輸出當前目錄所有二級子目錄
echo */*/* # 輸出當前目錄所有二級子目錄中的所有文件,有幾層子目錄,就必須寫幾層星號
打開 globstar 參數以后,** 可以匹配零個或多個任意深度子目錄(Bash 4.0 中新增)
shopt globstar # 查詢某個參數關閉還是打開,globstar 參數默認是關閉的
shopt -s globstar # 打開某個參數,打開 globstar 參數以后,** 可以匹配零個或多個子目錄
shopt -u globstar # 關閉某個參數
echo **/* # 輸出當前目錄以及【任意深度子目錄】中的所有文件
任一字符 []
- 方括號擴展
[...]可以擴展任意一個括號之中的字符 - 排除模式
[^...]和[!...]可以擴展任意一個不在方括號中的字符 - 如果需要匹配字符
[,可以放在方括號內任意位置,不支持匹配字符] - 如果需要匹配字符
-,只能放在方括號內部的開頭或結尾
echo [ab].txt # 方括號擴展 [...] 可以擴展任意一個括號之中的字符
echo [^ab] # 等價於 [!ab],表示擴展任意一個不在方括號中的字符
echo [[ab] # 如果需要匹配字符 [,可以放在方括號內任意位置,不支持匹配字符 ]
echo [-ab] # 如果需要匹配字符 -,只能放在方括號內部的開頭或結尾
echo [ab].bqt # 【[ab].bqt】如果不存在可匹配的文件名,就會原樣輸出
方括號擴展有一個簡寫形式[start-end],表示匹配一個連續的范圍。
[a-z]:所有小寫字母的字符[!a-z]:所有非小寫字母的字符[a-zA-Z]:所有小寫字母 + 大寫字母[a-zA-Z0-9]:所有小寫字母 + 大寫字母 + 數字program.[co]:文件program.c與文件program.oBACKUP.[0-9][0-9][0-9]:所有以BACKUP.開頭,后面是三個數字的文件名
字符類 [[:class:]]
[[:class:]] 表示一個字符類,擴展成某一類特定字符之中的一個。
[[:digit:]]:匹配任意數字 0-9[[:lower:]]:匹配任意小寫字母 a-z[[:upper:]]:匹配任意大寫字母 A-Z[[:alpha:]]:匹配任意英文字母[[:alnum:]]:匹配任意英文字母與數字[[:cntrl:]]:ASCII 碼 0-31 的不可打印字符[[:print:]]:ASCII 碼 32-127 的可打印字符[[:punct:]]:標點符號(除了 A-Z、a-z、0-9 的可打印字符)[[:graph:]]:匹配任意英文字母、數字、標點符號[[:blank:]]:空格和 Tab 鍵[[:space:]]:空格、Tab、LF(10)、VT(11)、FF(12)、CR(13)[[:xdigit:]]:匹配16進制字符(A-F、a-f、0-9)
echo [[:upper:]]* # 輸出所有以大寫字母開頭的文件名
echo [![:digit:]]* # 輸出所有不以數字開頭的文件名
echo [[:blank:]]* # 【[[:blank:]]*】如果不存在可匹配的文件名,就會原樣輸出
量詞語法 ?+*!@()
量詞語法用來控制模式匹配的次數。它只有在 Bash 的 extglob 參數打開的情況下才能使用,不過一般是默認打開的。
shopt extglob # 查詢某個參數關閉還是打開,extglob 參數默認是打開的
shopt -s extglob # 打開某個參數,打開 extglob 參數以后,可以使用量詞語法
shopt -u extglob # 關閉某個參數
?(pattern-list):匹配零個或一個模式*(pattern-list):匹配零個或多個模式+(pattern-list):匹配一個或多個模式@(pattern-list):只匹配一個模式!(pattern-list):匹配給定模式以外的任何內容
ls abc?(def) # 【abc abcdef】匹配以 abc 開頭、且以零個或一個 def 結尾的文件
ls abc+(.txt|.php) # 【abc.php abc.txt】匹配以 abc 開頭、且以 .txt 或 .php 結尾的文件
ls abc+(.txt) # 【abc.txt abc.txt.txt】匹配以 abc 開頭、且以 .txt 結尾的文件
ls a!(b)c.txt # 【aac.txt ac.txt】匹配除了 abc.txt 以外,以 a 開頭、且以 c.txt 結尾的文件
echo abc*(.bqt) # 【abc*(.bqt)】如果不存在可匹配的文件名,就會原樣輸出
字符串擴展 {}
大括號擴展 {...} 表示分別擴展成大括號里面的所有值。
- 各個值之間使用逗號分隔,值可以是多字符的模式
- 逗號前面可以沒有值,表示擴展的第一項為空
- 逗號前后不能有空格,否則,Bash 會認為這不是大括號擴展,而是獨立的參數
- 大括號可以嵌套,可以與其他模式聯用,並且總是先於其他模式進行擴展
- 大括號擴展不是文件名擴展,它總是會擴展的,這與方括號擴展
[...]完全不同
echo {1,2,3} # 【1 2 3】大括號擴展 {...} 表示分別擴展成大括號里面的所有值
ls {,a,abc}.txt # 依次訪問 .txt a.txt abc.txt 三個文件,而不管文件是否存在
echo a{a{1,2},b{3,4}} # 【aa1 aa2 ab3 ab4】支持嵌套
echo /bin/{cat,ba*} # 大括號也可以與其他模式聯用,並且總是先於其他模式進行擴展
大括號擴展可直接用於for循環。
for i in {1,2,4,白乾濤}
do
echo $i
done
- 大括號擴展的簡寫形式
{start..end}表示擴展成一個連續序列 - 大括號擴展另一個簡寫形式
start..end..step可指定擴展的步長 - 簡寫形式支持逆序、支持嵌套
echo {01..5} # 【01 02 03 04 05】擴展成一個連續序列
echo {0..8..2} # 【0 2 4 6 8】可指定擴展的步長
echo {a..c}{1,2} # 【a1 a2 b1 b2 c1 c2】多個簡寫形式連用,會有循環處理的效果
echo .{mp{5..3},mkv} # 【.mp5 .mp4 .mp3 .mkv】支持逆序,支持嵌套
echo {a1..3c} # 【{a1..3c}】遇到無法理解的簡寫時會原樣輸出,不會擴展
美元符號擴展
變量擴展 $
Bash 將美元符號$開頭的詞元視為變量,將其擴展成變量值。${!string*}或${!string@}返回所有匹配給定字符串string的變量名。
echo $SHELL # 【/bin/bash】
echo ${SHELL} # 【/bin/bash】變量名也可以放在 ${} 里面
echo ${!S*} # 返回所有以 S 開頭的變量名,如果不存在,則返回空
子命令擴展 $(...)
$(...) 可以擴展成另一個命令的運行結果,該命令的所有輸出都會作為返回值。
echo $(date) # 返回 date 命令的運行結果,注意 date 是一個命令而非一個變量
echo `date` # 將子命令放在反引號之中,也可以擴展成命令的運行結果
echo $(ls $(pwd)) # 子命令擴展可以嵌套
算術擴展 $((...))
$((...)) 可以擴展成整數運算的結果。
echo $((2 + 2)) # 4
模式擴展相關的 shopt 命令
shopt命令可以調整 Bash 的行為。它有好幾個參數跟通配符擴展有關。
shopt [optionname] # 查詢某個參數關閉還是打開
shopt -s [optionname] # 打開某個參數
shopt -u [optionname] # 關閉某個參數
- dotglob:默認關閉,可以讓擴展結果包括隱藏文件,即以點開頭的文件。
- nullglob:默認關閉,可以讓通配符不匹配任何文件名時,返回空字符串而非
原樣返回。 - failglob:默認關閉,可以讓通配符不匹配任何文件名時,直接報錯,而非繼續讓各個命令去處理。
- extglob:默認打開,可以讓 Bash 支持 ksh 的一些擴展語法。它的主要應用是支持
量詞語法。 - nocaseglob:默認關閉,可以讓通配符擴展不區分大小寫。
- globstar:默認關閉,可以讓
**匹配零個或多個子目錄(Bash 4.0 中新增)。
模式擴展使用注意點
- 通配符是先解釋,再執行:Bash 接收到命令以后,如果發現里面有通配符,會先進行通配符擴展,然后再執行命令。
- 文件名擴展在沒有可匹配的文件時,會原樣輸出。
- 所有文件名擴展只匹配單層路徑,無法匹配子目錄里面的文件(即:不能匹配路徑分隔符
/)。 - Bash 允許文件名使用通配符,即文件名包括特殊字符。這時引用文件名,需要把文件名放在
單引號或雙引號里面。
2022-01-02
