コマンドが失敗したときに出力をリダイレクトして終了するにはどうすればよいですか?

コマンドが失敗したときに出力をリダイレクトして終了するにはどうすればよいですか?

これは、スクリプト (通常は cronjobs) で stdout と stderr の両方をログに記録する方法です。

#!/bin/bash
mylog() {
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1"
}
(
mylog 'start'

some-command || mylog 'error' && exit 1

mylog 'end'
) >> /var/log/my-log.log 2>&1

いくつかのスクリプトでは、exit の代わりに return を使用しており、問題なく動作していますが、スクリプトを src でインクルードするか、関数で使用しない限り、return を使用できないと表示されます。そのため、exit に変更しましたが、問題は何もログに記録されないことです。>> 出力のリダイレクトが停止しているようです。もう 1 つの問題は、すべてではなくこのスクリプトのみを停止したいため、後で src でインクルードできないことです。

エラーが発生していなくてもすべてをログに記録したいので、出力リダイレクトを使用します。また、コマンドが適切な終了コードを返さないこともあるため、信頼できません。

では、エラー時に「戻る」にはどうすればよいのでしょうか? 「set -e」については知っていますが、スクリプトを停止するタイミングをより細かく制御できる方がよいと思います。

何かご意見は?

答え1

発生している動作を説明することはできませんが、考えられる修正方法は次のとおりです。

#!/bin/bash
マイログ(){
    echo "[$(日付 '+%Y-%m-%d %H:%M:%S')] $1"
}

マイメイン() {
        mylog '開始'

        何らかのコマンド || mylog 'エラー' && 1 を返す

        マイログ「終了」
    ) >> /var/log/my-log.log 2>&1
}

マイメイン

あるいは、関数定義からリダイレクトを削除しmymain、関数呼び出しに配置しますmymain

mymain >> /var/log/my-log.log 2>&1

(関数定義から括弧を削除することもできますmymain。)あるいは、IOをリダイレクトしたい場合は、全体スクリプトでは、リダイレクトをアクション ステートメントから分離できます。

実行 >> /var/log/my-log.log
実行 2>&1
マイメイン

あなたのアプローチが失敗する理由がわからないので、上記のどれかが期待どおりに機能する可能性が高い理由を説明することはできません。ただし、これらは同じことを行うためのわずかに異なる方法であり、それだけで十分かもしれません。ちなみに、一般的な理由で に変更した`date …`だけ$(date …)で、それがあなたの問題とは何の関係もないと思います。

答え2

Linux でコマンドを使用するのはどうでしょうかscreen? 自分でソリューションをプログラミングするつもりがない限り、これはうまくいきません。

関連情報