bash if文の動作に関する質問

bash if文の動作に関する質問

私は次の bash スクリプトを書きました。

if [ $(tmux has -t junk) ]
then
echo zero
else
echo one
fi

セッションが存在するかどうかに関係なく、常に 1 を返します。コマンドラインで tmux ステートメントを実行してから $? を実行して確認しました。期待どおりに動作し、セッションが存在する場合は 0、セッションが存在しない場合は 1 になります。if ステートメントが同じように動作しないのはなぜでしょうか。if ステートメントを以下のように変更してみました。

tmux has -t junk
if [ $? -eq 0 ]
then
echo zero
else
echo one
fi

上記は動作します。では、最初のステートメント ブロックの何が問題なのでしょうか?

答え1

前述のように、if [ $(tmux has -t junk) ]を に展開するとif [ ]、 false と評価されます。

次のようなものが使えます:

if tmux has -t junk; then
    echo OK
else
    echo ERR
fi

または、もっと短くしたい場合は、次のようになります。

tmux has -t junk || echo ERR

または

tmux has -t junk && echo OK || echo ERR

次のように、より適切な場合は否定することもできます。

! tmux has -t junk || echo OK
! tmux has -t junk && echo ERR || echo OK
etc.

編集:

また、コマンドが出力を生成する場合、その出力を/dev/null次のようにブラックホールにリダイレクトすることもできます。

 if my_cmd >/dev/null; then echo OK else; echo ERR; fi

コマンドがテキスト エラーを生成する場合は、次のようにして標準エラーもリダイレクトする必要があります。

 if my_cmd >/dev/null 2>&1; then echo OK else; echo ERR; fi

これから述べることは、すでによくご存知かもしれませんが、もう少し完全性を高めるために追加します。

前述のとおり、$?プログラムの戻り値を取得する唯一の方法です。

プログラムによっては戻り値が異なり、かなり明確な意味を持つ場合があります。

例えば:

mycmd
ecode=$?

case "$ecode" in
0) echo "Success";;
1) echo "Operation not permitted";;
2) echo "No such file or directory";;
esac

これにより、特定のエラーに対して適切なアクションを実行できます。

MySQLがインストールされている場合は、例えば次のように実行できます。ペロ:

for i in {0..50}; do perror $i; done
# And
for i in {1000..1050}; do perror $i; done

それを実感するために。

参照この答えOS固有のエラーに関連し、Open Groupsドキュメントにもリンクされていますエラー番号そしてエラー番号

または、こちらをご覧くださいSQLiteそしてその拡張されたもの

答え2

使用する場合:

if [ $(tmux has -t junk) ]

これはコマンドの出力をチェックしますtmux has -t junkが、戻り値はチェックしません。

したがって、最初のケースのように常に 1 が印刷されるため、tmux has -t junkコマンドは標準出力に何も印刷しないことを意味します。

最初のケースでは、

if [ $(tmux has -t junk) ] 

次のように評価されています

if [ ]

関連情報