導讀
[[ ]] 是我們比較熟悉的符號了,從第一篇開始我們就一直在用,但我一直沒有詳細介紹它的用法,只用到了它的一小部分功能。本文詳細介紹 [[ ]] 的用法。
比較字串
[[ ]] 最常用的功能之一是比較字串,這也是我們一直在用的功能。
# 匹配
% [[ abc == abc ]] && echo good
good
# = 和 == 是一樣的,最好統一使用一種
% [[ abc = abc ]] && echo good
good
# 不匹配
% [[ abc != abd ]] && echo good
good
# 正規表示式匹配
% [[ abc =~ a.c ]] && echo good
good
# 前者字元序比後者小
% [[ abc < bcd ]] && echo good
good
# 前者字元序比後者大
% [[ cde > bcd ]] && echo good
good
# 沒有 >= 和 <=
% [[ cde >= bcd ]] && echo good
zsh: parse error near `bcd`複製程式碼
除了在裡邊用等號、不等號之類比較外,還可以判斷字串是否為空:
% str=abc
# 判斷字串內容長度是否大於 0,等同於 (($#str))
% [[ -n "$str" ]] && echo good
good
% str=""
# 判斷字串是否為空,等同於 ((! $#str))
% [[ -z "$str" ]] && echo good
good複製程式碼
但這兩種用法,我們都有更方便的其他實現方法,沒有必要用它們。
判斷檔案
[[ ]] 另一類很重要的功能是判斷檔案,比如判斷某一個檔案是否存在、是否是目錄、是否可讀等等。
判斷 /bin/zsh 檔案是否存在:
% [[ -e /bin/zsh ]] && echo good
good
% [[ -e /bin/zshh ]] && echo good複製程式碼
-e 可以替換成如下的選項,用法是一致的:
選項 | 符合條件的檔案 |
---|---|
-b | 塊裝置檔案 |
-c | 字元裝置檔案 |
-d | 目錄 |
-e | 存在的任何檔案 |
-f | 普通檔案,含符號連結,不含目錄、裝置檔案、socket、FIFO |
-g | 設定了 setgid 的檔案 |
-h | 符號連結 |
-k | 設定了粘滯位(sticky bit)的檔案 |
-p | FIFO 檔案 |
-r | 對當前程式可讀的檔案 |
-s | 非空檔案 |
-u | 設定了 setuid 的檔案 |
-x | 對當前程式可執行的檔案 |
-w | 對當前程式可寫的檔案 |
-L | 符號連結(同 -h) |
-O | 被當前程式的使用者擁有的檔案 |
-G | 被當前程式的使用者組擁有的檔案 |
-S | socket 檔案 |
-N | atime 和 mtime 一樣的檔案 |
還有一個比較特殊的 -t 選項:
# $$ 是當前的程式 id
% ls /proc/$$/fd
0 1 10 11 2
% [[ -t 10 ]] && echo good
good
% [[ -t 3 ]] && echo good複製程式碼
-t 後要接數字(如果不是,相當於 0),判斷當前程式是否開啟了對應的 fd(程式預設會開啟 0、1、2 這三個 fd,分別對應標準輸入、標準輸出和錯誤輸出,此外每開啟一個檔案、管道或者網路連線,都會對應一個 fd,關掉後對應 fd 會消失)。
比較檔案
除了判斷單個檔案是否符合條件外,[[ ]] 還可以用來比較兩個檔案。
# file1 比 file2 新
% [[ file1 -nt file2 ]]
# file1 比 file2 舊
% [[ file1 -ot file2 ]]
# file1 和 file2 是否對應同一個檔案(路徑相同或者互為硬連線)
% [[ file1 -ef file2 ]]複製程式碼
比較數值
[[ ]] 也可以用來比較數值,注意不是用等號、大於號、小於號等等比較,有一系列專門的符號。通常我們沒必要用 [[ ]] 來比較數值,用 (( )) 更方便一些。
# -eq 是判斷兩個數值是否相等
% [[ 12 -eq 12 ]] && echo good
good複製程式碼
-eq 可以替換成下列符號,用法一樣:
符號 | 含義 |
---|---|
-eq | 相等 |
-ne | 不相等 |
-lt | < |
-gt | > |
-le | <= |
-ge | >= |
組合使用
# && 是邏輯與
% [[ a == a && b == b ]] && echo good
good
# || 是邏輯或
% [[ a == a || a == b ]] && echo good
good
# ! 是邏輯非
% [[ ! a == b ]] && echo good
good
# 可以一起用,! 優先順序最高,其次 &&,再次 ||
% [[ ! a == b && b == a || b == b ]] && echo good
good
# 如果不確定優先順序,可以加小括號
% [[ ((! a == b) && b == a) || b == b ]] && echo good
good複製程式碼
需要注意一下空格,[[ ]] 內側和內容之間需要空格隔開,== 兩邊也需要空格。如果是在 zsh 中直接敲入,! 後邊也要加一個空格,不然會被解析成歷史命令。
[ ] 符號
除了 [[ ]] 符號,[ ] 符號(它是古老的 test 命令化身)也可以用來判斷字串、檔案、數值等等,但功能沒有 [[ ]] 全,只支援上邊列的一部分功能(不支援 ==、=~、>、<、(、) ,並且邏輯與或的語法不一樣,不能調整優先順序,用起來很不方便),通常沒有必要使用 [ ](如需使用,可以 man test 檢視用法)。
總結
本文詳細介紹了 [[ ]] 的用法,基本覆蓋全面了。
參考
全系列文章地址:github.com/goreliu/zsh…
付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活定價,歡迎諮詢,微信 ly50247。