ファイルへのリダイレクトが失敗しても、スクリプトは引き続き実行されます。

ファイルへのリダイレクトが失敗しても、スクリプトは引き続き実行されます。

これはスクリプト出力をファイルにリダイレクトする一般的なシナリオです。権限の問題または何らかの理由で出力ファイルを生成できません。 (通常は製品のNFR要件に従って実装されたログファイルです。)これで、スクリプトの実行自体がブロックされます。出力ファイルを生成できない場合でもスクリプトの実行が続行するのを防ぐ方法はありますか?

答え1

私の提案は、すでに存在するロギングサブシステム()を使用することですsyslog。これにアクセスするコマンドラインツールはですlogger

ツールをuser適切な出力優先順位(エラー、警告、情報、デバッグなど)に設定し、タグをプログラムを表すラベルに設定すると、作業は完了です。

your_program 2>&1 | logger -t your_program -p user.info

答え2

teeコマンド出力を直接リダイレクトするのではなく、仲介者として機能できます。出力ファイルを開けなかったとしても止まりません。

$ cat out.sh
#!/bin/bash
outfile=${1-/dev/null}
echo hello | tee "$outfile"
echo done.
$ touch unwritable; chmod a-w unwritable
$ bash out.sh unwritable 
tee: unwritable: Permission denied
hello
done.

パイプの終了状態は最後のコマンドの終了状態になりますtee。パイプラインの最初の部分の終了状態が必要な場合は、Bash配列などを使用してPIPESTATUS取得できます。

出力コピーをスクリプトの標準出力にリダイレクトしたくない場合は、出力をteeにリダイレクトします。/dev/null

答え3

リダイレクトは関連コマンドが実行される前に処理されるため、リダイレクトが失敗するとコマンドはまったく実行されません。

だから

./script.sh >"$output"

ファイルへのリダイレクトが失敗した場合、スクリプトを正常に実行するには、$outputまずリダイレクトを手動で実行できるかどうかを検出する必要があります。

これは、たとえば出力をリダイレクトechoし、失敗した場合にキャプチャしてテストできます。

if ! echo >"$output" 2>/dev/null; then
    output=/dev/null
fi

./script.sh >"$output"

/dev/nullここでは、デフォルトの出力ファイルが利用できない場合は出力をリダイレクトします。出力を削除せずに標準出力に移動するには、代わりにYesを使用できます/dev/stdout/dev/null

関連情報