Pipefailはコマンド置換がpgrepを評価するのを防ぎますか?

Pipefailはコマンド置換がpgrepを評価するのを防ぎますか?

pgrep lftp -c私の目標は、スクリプトでコマンドを実行してすでに実行中であることをshell確認することです。lftp

ただし、次のスクリプトは「テスト」出力を超えません。その行を完全に削除した場合にのみスクリプトが実行されますpipefail。なぜ?

#!/usr/bin/env bash

set -e pipefail 

echo test

EXISTING="$(pgrep lftp -c)"
echo $EXISTING

ベストアンサー1

まず、シェルスクリプトのベストプラクティスガイドラインに関する注意事項:独自の変数名に大文字を使用しないでください。グローバル環境変数と命名の競合が発生する可能性があります。明確な例を挙げると、変数名をとして指定するとPATHグローバルPATH変数が上書きされ、実行可能ファイルが予想される場所に見つかりません。

今示したスクリプトに問題はありません。期待どおりに正確に動作します。set -eコマンドがゼロ以外の終了状態を返す場合、「コマンドが失敗した場合は終了」を意味します。何も見つからない場合はpgrepゼロ以外の状態で終了するため、スクリプトはそこで終了します。

手動で試してみると、実際に動作していることがわかります。

$ pgrep lftp -c
0
$ echo $?
1

これを防ぐには、代わりにwcを使用できます。行数が0の場合、ゼロ以外の状態で終了しないpgrep -cためです。wc

#!/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 pipefailset -e

#!/usr/bin/env bash

set -o pipefail 

echo test

existing="$(pgrep -c lftp)"
echo "Found $existing instances of lftp"

おすすめ記事