Zsh 開發指南(第十二篇 [[ ]] 的用法)

陌辭寒發表於2019-03-04

導讀

[[ ]] 是我們比較熟悉的符號了,從第一篇開始我們就一直在用,但我一直沒有詳細介紹它的用法,只用到了它的一小部分功能。本文詳細介紹 [[ ]] 的用法。

比較字串

[[ ]] 最常用的功能之一是比較字串,這也是我們一直在用的功能。

# 匹配
% [[ 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 檢視用法)。

總結

本文詳細介紹了 [[ ]] 的用法,基本覆蓋全面了。

參考

www.bash2zsh.com/zsh_refcard…

全系列文章地址:github.com/goreliu/zsh…

付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活定價,歡迎諮詢,微信 ly50247。

相關文章