Bash
Pipefail 阻止命令替換評估 pgrep?
我的目標是
pgrep lftp -c
在腳本中執行一個命令shell
來檢查是否lftp
已經在執行。但以下腳本永遠不會超出“測試”輸出。只有當我
pipefail
完全刪除該行時,腳本才會執行。為什麼?#!/usr/bin/env bash set -e pipefail echo test EXISTING="$(pgrep lftp -c)" echo $EXISTING
首先,關於 shell 腳本最佳實踐指南的說明:避免為您自己的變數名使用大寫字母,因為這可能會導致與全域環境變數的命名衝突。舉一個明顯的例子,如果你命名一個變數
PATH
,它將覆蓋全域PATH
變數,這意味著將不再在預期的位置找到執行檔。現在,在您向我們展示的腳本中,沒有問題。它完全按預期工作:您正在使用
set -e
這意味著“如果任何命令失敗則退出”,如果任何命令返回非 0 退出狀態。如果pgrep
沒有找到任何東西,它會以非 0 狀態退出,所以你的腳本就在那裡結束。如果您手動嘗試,您可以看到它的實際效果:
$ pgrep lftp -c 0 $ echo $? 1
為避免這種情況,您可以使用
wc
代替pgrep -c
,因為wc
如果行數為 0,則不會以非 0 狀態退出:#!/usr/bin/env bash set -e echo test existing="$(pgrep lftp | wc -l)" echo "Found $existing instances of lftp"
lftp
當沒有程序正在執行時,這會產生以下輸出:$ foo.sh test Found 0 instances of lftp
如果你想設置 bash 的
pipefail
選項,你需要set -o pipefail
,而不是set -e
. 所以也許你真正想要的是:#!/usr/bin/env bash set -o pipefail echo test existing="$(pgrep -c lftp)" echo "Found $existing instances of lftp"