1. 程式人生 > >指令碼寫一行echo也能寫出bug ? glob瞭解一下

指令碼寫一行echo也能寫出bug ? glob瞭解一下

## 背景 最近處理一個 `bug` 很有意思,有客戶反饋某個配置檔案解析失敗了,出錯的那行的內容就只有一個字母 `a`。 最開始以為是誰改動了處理的指令碼,但要到了問題程式碼中的指令碼,比較發現跟庫上是一樣的。 又經過一番查詢,才發現原來是指令碼中的一行 `echo` 引入的。 ## 問題程式碼 出問題的那行 `bash` 指令碼是這樣, `echo` 一個字串到某配置檔案中。 ```bash echo [partition] >> xxx.config ``` 這行平平無奇的程式碼在大多數人的環境下,確實是正常執行的,但某些情況下會出 `bug`,那就是當執行指令碼的目錄下存在特定檔案的時候。 ## 復現問題 看看例子,就明白了,其實就是匹配到了檔名。 ```bash /$ mkdir /tmp/glob_test && cd /tmp/glob_test /tmp/glob_test$ echo [partition] [partition] /tmp/glob_test$ touch a /tmp/glob_test$ echo [partition] a /tmp/glob_test$ touch o /tmp/glob_test$ echo [partition] a o ``` 也就是說出問題的機器上,執行指令碼的環境剛好存在一個名為 `a` 的檔案,於是這行指令碼的行為就改變了。 本意是寫入 `[partition]` 實際上寫入了`a` 解決也很簡單,加上引號。 ```bash echo "[partition]" >> xxx.config ``` ## glob簡介 解決了問題,再回頭認識下這個特性。這個叫 `glob` ,是 `bash` 的一個特性,可以實現檔名的通配。 最原始可追溯到 `UNIX V6`,後來就變成了 `shell` 內建的特性。 當字串包含了 `'?' '*' '['` 的時候就會觸發匹配,自動展開成匹配到的檔案列表,這個比正則表示式要弱一些,但勝在簡單實用。 大家可能經常用到類似於 `ls *.c'` 之類的功能,這就是 `glob` 生效的地方。 這裡不再詳細列出語法,請參考 `man 7 glob` 或網上諸多文章,例如阮一峰老師就分享過:[命令列萬用字元教程](http://www.ruanyifeng.com/blog/2018/09/bash-wildcards.html) 有一個要注意的地方就是,這個匹配如果失敗,就會原樣輸出,這也是上文的例子在多數情況下能工作的原因。 ## 寫在最後 寫指令碼時該加引號還是得加上的,養成良好的習慣可以少寫 `bug`。 另外,雖然 `shellcheck` 並不能檢測到這種情況,但對於提高指令碼質量還是很有幫助的,之前也介紹過,可參考:[shellcheck 幫助你寫出更好的指令碼](https://sourl.cn/qyeV7h) 本文地址: [https://www.cnblogs.com/zqb-all/p/12489524.html](https://www.cnblogs.com/zqb-all/p/12489524.html) 公眾號: [https://sourl.cn/nYkaiK](https://sourl.cn