引数が与えられた場合はファイルに出力し、そうでない場合は標準出力に出力する簡潔な方法

引数が与えられた場合はファイルに出力し、そうでない場合は標準出力に出力する簡潔な方法

ファイル名を引数として受け取らない限り、スクリプトを 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現在のスクリプトの stdout を別のファイルにリダイレクトするために使用できます。

[ -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}

関連情報