引数が与えられたらファイルに出力し、そうでなければstdoutに出力する簡潔な方法

引数が与えられたらファイルに出力し、そうでなければstdoutに出力する簡潔な方法

ファイル名を引数として取得しない限り、私のスクリプトがstdoutとして出力されることを望みます。明らかなアプローチは次のとおりです。

if [ -e "$1" ]; then
  command_with_output >$1
else
  command_with_output
fi

非常に醜くて反復的なので、これを行うためのよりきれいな方法が欲しいです。

以下を試しましたが、動作しません。

[ -e "$1" ] && outfile=$1 || outfile='&1'
command_with_output >$outfile

編集:これは答えの関連性を変えませんが、ファイルがまだ存在していない可能性があるためではなく、touch "$1" && outfile=$1実際に必要なものであることを質問した後に気づきました。[ -e "$1" ] && outfile=$1それは存在自体ではありません。回答が同期されない可能性があるため、質問を変更しないでください。

答え1

exec現在のスクリプトの標準出力を別のファイルにリダイレクトするために使用できます。

[ -e "$1" ] && exec > $1
command_with_output

答え2

別のアプローチは、渡さ$1れた場合はファイル名を使用し、そうでない場合はファイル名を使用することです/dev/stdout(これはLinuxではシンボリックリンクであり/proc/self/fd/1、他の多くのUNIXバリアントでは同じ意味を持つデバイスノードです)。たとえば、スクリプトの上部に次のように入力します。

if [ -e "$1" ]; then
    filename=$1
else
    filename=/dev/stdout
fi

次に、各コマンドの出力を次にリダイレクトします。$filename

答え3

これは、ファイル引数を除く引数を受け入れない場合でも機能します。

command_with_output > ${1:-/dev/stdout}

編集:またはエラーに興味があるかもしれないので、より良いです。

command_with_output &> ${1:-/dev/stdout}

関連情報