2019年4月23日 星期二

Linux Shell Scripting: 符號連結檔案的存在判斷 Link Exist or Linked Target Exist ?


最近因為工作上的需求,接觸到不少 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() 讀寫檔案時也一樣,因此在開發上若遇到符號連結務必多加留意。

參考資料: