最近因為工作上的需求,接觸到不少 Linux Shell 相關的系統應用,其中遇到了一個蠻值得注意的細節,就是在使用
test 指令 (或是中括號 [] ) 來製作判斷可能為符號連結 (symbolic link) 的位置,該
『檔名』是否存在時,若只單獨考慮 exist (-e) 或是 is link (-L) 判斷條件是不夠的,必須同時使用兩者才能正確判斷。
為了釐清兩者的關係,在這裡做了個小實驗
## 新增一個普通檔案 "normalfile123"
$ touch "normalfile123"
$ if [ -e "normalfile123" ]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
$ if [ -L "normalfile123" ]; then echo "TRUE"; else echo "FALSE"; fi
FALSE
## 不存在的檔名 "notexisting1234"
$ if [ -e "notexisting1234" ]; then echo "TRUE"; else echo "FALSE"; fi
FALSE
$ if [ -L "notexisting1234" ]; then echo "TRUE"; else echo "FALSE"; fi
FALSE
## 建立指向 "normalfile123" 的符號連結 "link123"
$ ln -s "link123" "normalfile123"
$ if [ -e "link123" ]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
$ if [ -L "link123" ]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
## 刪除 "normalfile123" ;使符號連結 "link123" 成為無效連結
$ rm "normalfile123"
$ if [ -e "link123" ]; then echo "TRUE"; else echo "FALSE"; fi
FALSE
$ if [ -L "link123" ]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
實驗中得到的結果:
|
存在的普通檔案 |
不存在的檔名 |
有效符號連結 |
無效符號連結 |
-e |
True |
False |
True |
False |
-L |
False |
False |
True |
True |
-e or -L |
True |
False |
True |
True |
結果其實不難推測得到,在讀寫 Symbolic Link 類型的檔案時,系統預設是
直接看到連結指向的檔案而非連結本身,就連在使用 C++ 的標準函式庫 fopen() 讀寫檔案時也一樣,因此在開發上若遇到符號連結務必多加留意。
參考資料: