測試工程師到底要不要熟練使用 shell?

作者:Will,軟體質量保障專家,DevOps 落地專家,公眾號撩保星球。曾擔任某大型全球分散式儲存產品測試負責人,以及某容器雲平臺解決方案公司的 DevOps 產品測試架構師。現就職一家零售業大資料智慧解決方案公司,擔任產品質量負責人。

掌握這篇 shell 技巧,就能應付 80% 的測試場景需求了

引言

都 21 世紀 20 年代了,為什麼還是少不了遠古時期的 shell script ?Python 那麼火,難道不香嗎?

對於我這樣一個左手 Shell 右手 Python 的人來說,只能說這個真的跟工作任務的場景有關。

特別是軟體測試工程師,不同於軟體開發工程師,不需要像開發工程師那樣對一門程式語言的極致精通,測試工程師的職責是保障產品質量,工具(包括程式語言)的使用是為了更便捷更高效的輔助工作,所以當工作場景需要在 Unix/Linux 平臺上進行各種操作的時候,Shell 作為直接跟系統核心打交道的命令語言有著天然的優勢和便利,硬要用 Python 不是為難自己麼?

事實上,我寫下這篇的原因和動力,正是我那些測試工程師同事們的需求。

從哪裡開始

Shell 命令其實非常多,不過如果我們不是系統運維,而是作為一個 Linux 環境上的測試工程師而言,掌握 20 個左右就足夠了。

其中有大部分是基礎中的基礎,只要用 Linux 就會用到,所謂的高階一點的用法無非是程式設計,或者是命令與命令之間用管道符連線組成複雜的長命令。

基礎命令

這些命令多是對磁碟/目錄/檔案的操作,單獨使用非常簡單。

測試工程師到底要不要熟練使用 shell?

還有一些命令是檢視系統資源,也是會經常使用到的。

測試工程師到底要不要熟練使用 shell?

混搭

除了以上基礎命令,還有一些很常用的命令,比如 echo 用來輸出字串,sed 和 awk 都是用來處理檔案內容的,在多命令混搭或寫指令碼的時候非常有用。

這些命令單獨看的時候,其實沒有什麼難度,主要是在想獲取某種效果的時候需要混搭,需要靠 | 或> 或 >>連線,比如:

測試工程師到底要不要熟練使用 shell?

對於相對複雜的查詢獲取,只要你願意,可以繼續用管道符 | 一直傳遞下去,從而達到預期目標。

這其中相對較難的是 sed 和 awk,如果對上面的例子還是沒有概念的話,繼續看以下兩段:

sed 用得最多的替換輸出或者檔案中的字串,比如要上面的例子,要替換 /etc/hosts 中我們新增的 QualitySphere。github。io 這行的指定內容:

grep QualitySphere /etc/hosts | sed ‘s/github/gitee/g’

這在輸出的時候就把 github 欄位換成了 gitee,格式為 ‘s/string_a/string_b/g’,s是告訴 sed 我們要進行替換操作,g 是替換所有的 string_a,如果沒有 g 就只替換搜尋到的第一個。

有時候我們的需求是直接修改一個檔案中的目標字串,使用 sed 的時候加上 -i 引數,比如 sed -i ‘s/github/gitee/g’ /etc/hosts 執行之後,該檔案內容直接被修改了,不過值得注意的是,如果是在 Mac 上執行該命令,通常 Mac 預設的 shell 是 zsh,與 Linux 預設的 bash 不太一樣,-i 後面要帶個值,空值就好,sed -i ‘’ ‘s/QualitySphere/qsphere/g’ /etc/hosts

要想刪除該行其實是有 d引數的,不過為了減少記憶,依舊可以簡單粗暴的用替換的方法,因為sed支援正則表示式,因此使用 sed -i ‘s/。*qsphere。*//g’ /etc/hosts 也能達到效果。

awk則是更是超級強大,甚至有很多 AWK 程式設計實戰的技術貼,沒錯,這貨是個程式設計語言,我有幸體驗過它效能的強大。

不過通常我們比較常用的是透過它來獲取指定目標位置的字串, 比如我們去獲取記憶體的值,free -h | grep Mem | awk ‘{print $2}’

首先會 grep 出記憶體那一行,如果以空格為分隔符,我們會看到記憶體的值是在第 2 列,因此用 ‘{print $2}’ 來獲取第 2 列的值。

有時候分隔符只用空格是肯定不行的,比如我要獲取一個 IP 的最後一個數值,可以指定。為分隔符,echo “192。168。1。199” | awk -F ‘。’ ‘{print $4}’ 引數 -F 指定分割符,然後獲取第 4 個值。

指令碼

很多時候光有命令還是不夠的,總要寫一些指令碼,把重複的事情交給機器。

通常,迴圈和邏輯判斷就已經夠用了,高階用法無非是高效且優美。

測試工程師到底要不要熟練使用 shell?

舉些例子,注意其中的符號及空格的細節。

判斷兩個字串

A=willB=bxwillif [[ “$A” == “$B” ]]; then # 字串用 “。。。” 括起來,用 [[ 。。。 ]] 來判斷 echo PASSelse echo FAILfi

判斷兩個數字

A=1B=2if (( $A == $B )); then # 數字不需要 “。。。”,用 (( 。。。 )) 來判斷 echo PASSelse echo FAILfi

還有一些邏輯判斷很常用

if [[ -f /etc/hosts ]]; then # 判斷檔案是否存在 echo PASSelse echo FAILfiif [[ -d /etc ]]; then # 判斷目錄是否存在 echo PASSelse echo FAILfiA=willif [[ -z “$A” ]]; then # 判斷字串是否為空 echo PASSelse echo FAILfiif [[ -n “$A” ]]; then # 判斷字串是否不為空 echo PASSelse echo FAILfi

for 迴圈

for i in `seq 1 10` # seq 1 10 直接生成 1-10 的數字,用鍵盤左上角的 ` 符號括起來,會先執行該命令do echo $idone

while 迴圈

while true # 看,這是一個死迴圈do sleep 1 # 停頓 1 秒,在指令碼中也是很常用的命令 echo PASSdone

其他技巧

最實用的莫過於後臺執行了,比如你寫了一個指令碼叫 check_me。sh,想丟在後臺執行,nohup 。/check_me。sh & 它就會使該指令碼在後臺執行,並且日誌會存在當前目錄的 nohup。out 中。

當然,丟後臺執行那是寫好了指令碼,最傷心的事情莫過於,你正在除錯,敲了一堆命令,坐等執行結果的時候,突然斷網,嗚呼哀哉,一夜回到解放前,Linux 自帶 screen 工具,連線到終端準備大展拳腳之前,順手輸入 screen 開啟一個視窗,若在一陣敲打過程中突然掉線,莫方,再次登入終端,嘗試 screen -ls 一下,你會看到之前開啟的視窗在列表中,開頭的那竄數字就是它的 ID,screen -r $ID 就又回到之前的視窗,所有的操作又回到了你的眼前。

同樣的效果有個更不錯的工具 tmux,則需要自行安裝,它比 screen 更友好一些,可自行了解。

文中未涉及到的用法和命令,感興趣的可以去搜索一番,或者直接在命令列用 man 命令來學習。