8

基本的に、別のコマンドの失敗 (ゼロ以外の終了コード) をアサートし、失敗したときにメッセージを出力する関数を実装しようとしています。

これが私の機能です:

function assert_fail () {
    COMMAND=$@
    if [ `$COMMAND; echo $?` -ne 0 ]; then 
        echo "$COMMAND failed as expected."
    else
        echo "$COMMAND didn't fail"
    fi
}

# This works as expected
assert_fail rm nonexistent

# This works too
assert_fail rm nonexistent nonexistent2

# This one doesn't work
assert_fail rm -f nonexixtent

コマンドにオプションを追加するとすぐに機能しません。上記の出力は次のとおりです。

rm: cannot remove `nonexistent': No such file or directory
rm nonexistent failed as expected.
rm: cannot remove `nonexistent': No such file or directory
rm: cannot remove `nonexistent2': No such file or directory
rm nonexistent nonexistent2 failed as expected.
rm -f nonexistent didn't fail

コマンドを二重引用符で囲んでみましたが、役に立ちませんでした。上記の 3 番目の呼び出しでは、他の 2 つの呼び出しと同様の出力が生成されると思います。

あらゆる/すべての助けに感謝します!

4

2 に答える 2

12

@rici は、あなたが見ている問題を正しく指摘しましたが、ラッパー関数には実際の問題がいくつかあります。まず、引数のスペース (およびその他の変な文字) が正しく保持されません。COMMAND=$@(またはCOMMAND="$@") は、すべての引数を 1 つの文字列にマージし、引数間のスペースと引数内のスペースの区別を失います。それらをまっすぐに保つ"$@"には、変数に格納せずに直接使用するか、配列として格納します(COMMAND=("$@")、次に として実行します"${COMMAND[@]}")。第 2 に、コマンドが標準出力に何かを出力すると、終了ステータス チェックに大混乱が生じます。@chepnerが言ったように、直接テストしてください。これが私の提案された書き直しです:

function assert_fail () {
    if "$@"; then 
        echo "$* didn't fail"
    else
        echo "$* failed as expected."
    fi
}

私がエコー コマンドを実行した方法では、引数内のスペースの区別が失われることに注意してください。これが問題になる場合は、echo コマンドを次のように置き換えます。

printf "%q " "$@"
echo "didn't fail"

printf "%q " "$@"
echo "failed as expected."
于 2012-10-16T03:14:03.967 に答える
6

rm -f存在しないファイルで失敗することはありません。ラッパーとは関係ありません。参照man rm:

OPTIONS
       -f, --force
              ignore nonexistent files, never prompt
于 2012-10-15T15:36:52.283 に答える