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