bash 教程-2 shell 字符串 轉義 模式擴展 特殊符號 [MD]


博文地址

我的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.o
  • BACKUP.[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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM