1:

1:

私はシステムに問題がないかどうかを確認するために一連のスクリプトを実行するC ++監視デバイスを作成しました。

コードが少しトリッキーで、ここには表示されませんが、次のシステムコールに対応します。

int const r(system("/bin/sh /path/to/script/test-health"));

rステートメントにコマンドが欠落してスクリプトが失敗した場合にのみifゼロです。スクリプトに積極的な部分があります。

set -e
[...]
if unknown_command arg1 arg2
then
[...]

明らかにunknown_command失敗した理由は…不明。その時点で私が始めたので、スクリプトは終わりましたset -e

ただし、この場合、終了コードは0になります。

この場合、終了コード1を取得する方法はありますか?

つまり、問題は、バグが存在することを確認するためにテストを追加することなくバグを検出することですunknown_command。私はこれを行う方法を知っています。

if ! test -x unknown_command
then
    exit 1
fi

私のポイントは、スクリプトの作成時にunknown_command直接インストールするときにスクリプトがあると予想しましたが、問題が発生した場合、または誰かがすべてをインストールせずに他のシステムにスクリプトをコピーした場合は、スクリプトを実行するときに何が間違っているのかを知りたいということです。 。

答え1

POSIX規格では、~についてset -e:

-e、または予約語の後の複合リスト、予約語で始まるパイプ、または最後のAND-ORリストを除くすべてのコマンドを実行するときは、この設定は無視する必要があります。whileuntilifelif!

これはif、ステートメント内で不明なコマンドを実行した場合いいえ実行中にスクリプトが終了しますset -e。あるいは、むしろset -eシャットダウンを引き起こさない。


ユーザーは、呼び出されるユーティリティのフルパスを使用しない限り、command -v現在のユーティリティが存在するかどうかをテストしますPATH。この場合、-x質問が示すようにテストで十分です。

また見なさい: 「which」を使わないのはなぜですか?それでは何を使うべきですか?

答え2

その時点で私が始めたので、スクリプトは終わりましたset -e

これは嘘です。

よく使用されるスクリプト:

$猫。/ウィブル
セット
揺れるとエコーも揺れます。 ;そうでなければ、エコーは揺れません。 ;ペイ
エコーは削除されません。
タイプスイング||実行エラー
実行する
$

未知の命令をテストする方法を知っていると言われました。

Almquistシェルは次のとおりです/bin/sh

$ /bin/sh ./weeble ;エコ$?
./weeble:weeble: 見つかりません
揺れがありません。
倒れません。
スイング:見つかりません
1
$ /bin/sh -e ./weeble エコ$?
./weeble:weeble: 見つかりません
揺れがありません。
倒れません。
スイング:見つかりません
1
$

コーエンシェルは次のとおり/bin/shです

$ /bin/sh ./weeble ;エコ$?
./weeble[2]:weeble: 見つかりません
揺れがありません。
倒れません。
スイングが見つかりません
1
$ /bin/sh -e ./weeble エコ$?
./weeble[2]:weeble: 見つかりません
揺れがありません。
倒れません。
スイングが見つかりません
1
$

Bourne Againシェルは次のとおりです/bin/sh

$/bin/exec -a /bin/sh /usr/local/bin/bash ./weeble echo$?
./weeble: 行 2: wobble: コマンドが見つかりません。
揺れがありません。
倒れません。
./weeble: 4行: タイプ: スイング: 見つかりません
1
$ /bin/exec -a /bin/sh /usr/local/bin/bash -e ./weeble echo$?
./weeble: 行 2: wobble: コマンドが見つかりません。
揺れがありません。
倒れません。
./weeble: 4行: タイプ: スイング: 見つかりません
1
$

Zシェルは次のとおりです/bin/sh

$/bin/exec -a /bin/sh /usr/local/bin/zsh ./weeble echo$?
./weeble:2: コマンドが見つかりません:weeble
揺れがありません。
倒れません。
スイングが見つかりません
1
$ /bin/exec -a /bin/sh /usr/local/bin/zsh -e ./weeble echo$?
./weeble:2: コマンドが見つかりません:weeble
揺れがありません。
倒れません。
スイングが見つかりません
1
$

あなたの質問は何が起こらなかったのかを回避する方法についての質問であり、前提とタイトルは嘘なので答えることはできません。

答え3

次のように設定されているifため終了しません。set -e

#!/bin/sh

set -e

if unknown_command; then
    echo "On true, exit code $?"
else
    echo "on false, exit code $?"
fi

echo "after if, exit code $?"

印刷します(テストされたすべてのシェルから他のエラーメッセージを含む):

sh            : … : unknown_command: not found                                    
on false, exit code 127                                                                                                          
after if, exit code 0 

設定またはset -e設定解除できます。


不足しているコマンドを検索するには、終了コード127 1をキャプチャしてください。

#!/bin/sh

if unknown_command; then
    echo "On true, exit code $?"
else
    ec=$?
    if [ "$ec" = '127' ]; then
        echo "the command failed because it does not exist"
        exit 127
    fi
    echo "on false, exit code $ec"
fi

echo "after if, exit code $?"

次のように実行されます。

$ ./script
./script: 5: ./script: unknown_command: not found
the command failed because it does not exist


1紹介終了コード 127

答え4

次の 2 つのいずれかを実行する必要があります。

1:

不明なコマンドarg1 arg2
後続のコマンド

失敗するとset -eスクリプトが終了しますunknown_command。なぜそのようなことを言ったのですifか?

2:

arg1 arg2 コマンドが不明な場合
それから
    後続のコマンド
その他
    エラーメッセージの発行
    必要なクリーンアップを実行します。
    1番出口
フィリピン諸島

関連情報