
私は次の 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ドキュメントにもリンクされていますエラー番号そしてエラー番号。
答え2
使用する場合:
if [ $(tmux has -t junk) ]
これはコマンドの出力をチェックしますtmux has -t junk
が、戻り値はチェックしません。
したがって、最初のケースのように常に 1 が印刷されるため、tmux has -t junk
コマンドは標準出力に何も印刷しないことを意味します。
最初のケースでは、
if [ $(tmux has -t junk) ]
次のように評価されています
if [ ]