4

コマンドと引数の変数を使用して、共通の引数で一般的に使用するプログラムを起動する BASH スクリプトがいくつかあります。呼び出しは次のように最後に表示されます。

$PROGRAM $ARG1 $ARG2 &

ここで、デフォルトで出力を stderr および stdout にリダイレクトしたいと考えて/dev/nullいます。-vスクリプトへの切り替え( =詳細)でそれを無効にできるようにしたい。しかし、変数に割り当てようとすると"2>&1 > /dev/null"、たとえばREDIRECTION、(詳細が指定されている場合はクリアします)、次のように呼び出そうとします:

$PROGRAM $ARG1 $ARG2 $REDIRECTION &

リダイレクト ディレクティブは、引数としてプログラムに渡されます。これを行う方法はありますか?または、「詳細度」に応じて、リダイレクト ディレクティブを使用する場合と使用しない場合の 2 つの個別の呼び出し行を持つソリューションを使用する必要がありますか?

4

3 に答える 3

4

1 つのオプションは、ビルトインを使用することですeval。これは、引数を Bash コマンドのように処理し、リダイレクト演算子などを処理します。ただし、すべてevalの引数を再処理するため、かなり危険です。これは、既に適切に処理されたものであっても、完全に行われなければ、奇妙または安全でない動作を引き起こす可能性があります。

コマンドの 2 つのバージョン間の唯一の問題のある違いは、リダイレクトの有無であるため、より良いオプションはexec組み込みを使用することです。このコマンド:

exec >/dev/null 2>&1

シェルスクリプトの残りの部分の STDOUT と STDERR を にリダイレクトします/dev/null。このコマンド:

[[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1

exec >/dev/null 2>&1 が空白でない限り 実行さ$IS_VERBOSEれます。空白の場合は何もしません。[[ "$IS_VERBOSE" ]](冗長性を検出するために既に使用している任意の種類の条件式に置き換えることができます。)

したがって、あなたが望むのは次のようなものです:

(
    [[ "$IS_VERBOSE" ]] || exec >/dev/null 2>&1
    "$PROGRAM" "$ARG1" "$ARG2" &
)

括弧( ... )はサブシェルを設定するためのものであるため、execコマンド (実行された場合) は).

(ちなみに、私はあなた2>&1 > /dev/null> /dev/null 2>&1: に変更したことに注意してください。順序が重要です。)

于 2012-10-17T23:38:52.777 に答える
1

シェル構文をパラメーターにエンコードしようとするのではなく、各リダイレクト演算子のデフォルトの宛先をパラメーターに入れ、デフォルトをオーバーライドするメソッドを許可します。

# A little bash-specific, but appropriate defaults should exist for the shell
# of your choice.
STDOUT=/dev/stdout
STDERR=/dev/stderr

if some-test; then
    STDOUT=some-other-file
fi

if some-other-test; then
    STDERR=different-file
fi

$PROGRAM $ARG1 $ARG2 > $STDOUT 2> $STDERR
于 2012-10-18T13:01:36.207 に答える
0

任意のコマンドラインを作成し、evalを使用して実行できます。

line="echo hello"
if ....
    line="$line > junk.out"
fi

eval $line

(しかし、私はおそらく、読みやすく理解しやすいとあなたが提案する2行のアプローチを採用するでしょう...)

于 2012-10-17T23:38:14.493 に答える