你所不了解的 Bash:關於 Bash 數組的介紹

我們需要的第二個語法是如何把我們剛剛解析的值添加到數組中。完成這個任務的語法看起來很熟悉:

myArray+=( "newElement1" "newElement2" )

參數掃描

萬事具備,執行參數掃描的腳步如下:

allThreads=(1 2 4 8 16 32 64 128)

allRuntimes=()

for t in ${allThreads[@]}; do

runtime=$(./pipeline --threads $t)

allRuntimes+=( $runtime )

done

就是這個了!

還有什麼能做的?

這篇文章中,我們講過使用數組進行參數掃描的場景。我敢保證有很多理由要使用 Bash 數組,這裡就有兩個例子:

日誌警告

本場景中,把應用分成幾個模塊,每一個都有它自己的日誌文件。我們可以編寫一個 cron 任務腳本,當某個模塊中出現問題標誌時向特定的人發送郵件:

# 日誌列表,發生問題時應該通知的人

logPaths=("api.log" "auth.log" "jenkins.log" "data.log")

logEmails=("jay@email" "emma@email" "jon@email" "sophia@email")

# 在每個日誌中查找問題標誌

for i in ${!logPaths[@]};

do

log=${logPaths[$i]}

stakeholder=${logEmails[$i]}

numErrors=$( tail -n 100 "$log" | grep "ERROR" | wc -l )

# 如果近期發現超過 5 個錯誤,就警告負責人

if [[ "$numErrors" -gt 5 ]];

then

emailRecipient="$stakeholder"

emailSubject="WARNING: ${log} showing unusual levels of errors"

emailBody="${numErrors} errors found in log ${log}"

echo "$emailBody" | mailx -s "$emailSubject" "$emailRecipient"

fi

done

API 查詢

如果你想要生成一些分析數據,分析你的 Medium 帖子中用戶評論最多的。由於我們無法直接訪問數據庫,SQL 不在我們考慮範圍,但我們可以用 API!

endpoint="https://jsonplaceholder.typicode.com/comments"

allEmails=()

# 查詢前 10 個帖子

for postId in {1..10};

do

# 執行 API 調用,獲取該帖子評論者的郵箱

response=$(curl "${endpoint}?postId=${postId}")

# 使用 jq 把 JSON 響應解析成數組

allEmails+=( $( jq '.[].email' <<< "$response" ) )

done

注意這裡我是用 jq 工具 從命令行裡解析 JSON 數據。關於 jq 的語法超出了本文的範圍,但我強烈建議你瞭解它。

請等等,還有很多東西!

由於我們在本文講了很多數組語法,這裡是關於我們講到內容的總結,包含一些還沒講到的高級技巧:

語法效果arr=()創建一個空數組arr=(1 2 3)初始化數組${arr[2]}取得第三個元素${arr[@]}取得所有元素${!arr[@]}取得數組索引${#arr[@]}計算數組長度arr[0]=3覆蓋第 1 個元素arr+=(4)添加值str=$(ls)把 ls 輸出保存到字符串arr=( $(ls) )把 ls 輸出的文件保存到數組裡${arr[@]:s:n}取得從索引 s 開始的 n 個元素

最後一點思考

正如我們所見,Bash 數組的語法很奇怪,但我希望這篇文章讓你相信它們很有用。只要你理解了這些語法,你會發現以後會經常使用 Bash 數組。

Bash 還是 Python?

問題來了:什麼時候該用 Bash 數組而不是其他的腳本語法,比如 Python?

對我而言,完全取決於需求——如果你可以只需要調用命令行工具就能立馬解決問題,你也可以用 Bash。但有些時候,當你的腳本屬於一個更大的 Python 項目時,你也可以用 Python。

比如,我們可以用 Python 來實現參數掃描,但我們只用編寫一個 Bash 的包裝:

import subprocess

all_threads = [1, 2, 4, 8, 16, 32, 64, 128]

all_runtimes = []

# 用不同的線程數字啟動管線

for t in all_threads:

cmd = './pipeline --threads {}'.format(t)

# 使用子線程模塊獲得返回的輸出

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)

output = p.communicate()[0]

all_runtimes.append(output)

由於本例中沒法避免使用命令行,所以可以優先使用 Bash。

羞恥的宣傳時間

如果你喜歡這篇文章,這裡還有很多類似的文章! 在此註冊,加入 OSCON ,2018 年 7 月 17 號我會在這做一個主題為 你所不瞭解的 Bash 的在線編碼研討會。沒有幻燈片,不需要門票,只有你和我在命令行裡面敲代碼,探索 Bash 中的奇妙世界。


via: https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays


分享到:


相關文章: