Bash
Shell 在 for 循環中的算術表達式處靜默退出
我已經為 ssh 遠端主機編寫了一個腳本,執行命令,將輸出保存到文件,並檢查輸出。但是
(( success++ ))
當迭代 array 中的第一項時,它總是在 line 處靜默退出workers
。如果我替換(( success++ ))
為echo "process $worker"
,它將正常工作並列印所有主機。我無法弄清楚出了什麼問題。#!/bin/bash set -x set -e workers=('host-1' 'host-2' 'host-3') output_dir=$(mktemp -d) for worker in ${workers[@]}; do ssh $worker ' echo abc echo OK ' > "$output_dir/$worker" & done echo "waiting..." sleep 3 wait success=0 regexp='OK$' for worker in ${workers[@]}; do output=`cat "$output_dir/$worker"` if [[ "$output" =~ $regexp ]]; then (( success++ )) fi done echo "Total ${#workers[@]}; success: $success; failure: $((${#workers[@]} - success))"
一個簡單的例子應該解釋為什麼:
$ ((success++)) $ echo $? 1
原因是任何產生零數值的算術運算都會返回 1。我不知道該說什麼——Bash 已經足夠讓全世界知道了。
這是
-e
設置的結果。退出程式碼為 1(非零)的任何命令都將觸發退出。這個腳本工作正常:
#!/bin/bash (( success++)) echo "Still going 1 $success"
這不
#!/bin/bash set -e (( success++)) echo "Still going 1 $success"
解決方案
最簡單的就是去掉
set -e
線。如果這不是一個選項,請使用此:
(( ++success ))
其他選擇:
#!/bin/bash set -e success=0 success=$(( success+1 )) echo "still going 1 $success" success=0 (( success=success+1 )) echo "still going 2 $success" success=0 (( success+=1 )) echo "still going 3 $success" success=0 (( ++success )) echo "still going 4 $success" success=0 (( success++ )) echo "still going 5 $success"
只有選項編號 5 的退出程式碼為 1。
其他(任何變數值的更複雜的解決方案
a
)。第一個使用(POSIX) 冒號 (
:
) 內置使其與 POSIX 兼容。: $(( a+=1 )) ; echo "6 $a $?" ## Valid Posix (( a++ )) || true ; echo "7 $a $?" (( a++ )) || : ; echo "8 $a $?" (( a++ , 1 )) ; echo "9 $a $?" (( a++ | 1 )) ; echo "10 $a $?"