腳本寫一行echo也能寫出bug ? glob瞭解一下

背景

最近處理一個 bug 頗有意思,有客戶反饋某個配置文件解析失敗了,出錯的那行的內容就只有一個字母 ahtml

最開始覺得是誰改動了處理的腳本,但要到了問題代碼中的腳本,比較發現跟庫上是同樣的。正則表達式

又通過一番查找,才發現原來是腳本中的一行 echo 引入的。shell

問題代碼

出問題的那行 bash 腳本是這樣, echo 一個字符串到某配置文件中。bash

echo [partition] >> xxx.config

這行平平無奇的代碼在大多數人的環境下,確實是正常運行的,但某些狀況下會出 bug,那就是當運行腳本的目錄下存在特定文件的時候。url

復現問題

看看例子,就明白了,其實就是匹配到了文件名。命令行

/$ 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 的文件,因而這行腳本的行爲就改變了。code

本意是寫入 [partition] 實際上寫入了ahtm

解決也很簡單,加上引號。blog

echo "[partition]" >> xxx.config

glob簡介

解決了問題,再回頭認識下這個特性。這個叫 glob ,是 bash 的一個特性,能夠實現文件名的通配。教程

最原始可追溯到 UNIX V6,後來就變成了 shell 內建的特性。

當字符串包含了 '?' '*' '[' 的時候就會觸發匹配,自動展開成匹配到的文件列表,這個比正則表達式要弱一些,但勝在簡單實用。

你們可能常常用到相似於 ls *.c' 之類的功能,這就是 glob 生效的地方。

這裏再也不詳細列出語法,請參考 man 7 glob 或網上諸多文章,例如阮一峯老師就分享過:命令行通配符教程

有一個要注意的地方就是,這個匹配若是失敗,就會原樣輸出,這也是上文的例子在多數狀況下能工做的緣由。

寫在最後

寫腳本時該加引號仍是得加上的,養成良好的習慣能夠少寫 bug

另外,雖然 shellcheck 並不能檢測到這種狀況,但對於提升腳本質量仍是頗有幫助的,以前也介紹過,可參考:shellcheck 幫助你寫出更好的腳本

本文地址: http://www.javashuo.com/article/p-eifusgem-dh.html

公衆號: https://sourl.cn/nYkaiK

相關文章
相關標籤/搜索