解決策 1:
私は通常、すべてのスクリプトの先頭に次のようなものを置きます (特にデーモンとして実行する場合):
#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':
説明:
<オール>
exec 3>&1 4>&2
ファイル記述子を保存して、リダイレクト前の状態に復元したり、次のリダイレクト前の状態に出力するために使用したりできるようにします。
trap 'exec 2>&4 1>&3' 0 1 2 3
特定のシグナルのファイル記述子を復元します。サブシェルの終了時に復元する必要があるため、通常は必要ありません。
exec 1>log.out 2>&1
stdout
をリダイレクト ファイル log.out
へ stderr
をリダイレクトします stdout
まで .同じファイルに移動する場合は、順序が重要であることに注意してください。 stdout
しなければならない stderr
の前にリダイレクトされる stdout
にリダイレクトされます .
それ以降、コンソールに出力を表示するには (たぶん)、 &3
にリダイレクトするだけです。 .たとえば、
echo "$(date) : part 1 - start" >&3
stdout
のどこにでも行きます 上記の 3 行目を実行する前に、おそらくコンソールに指示されました。
解決策 2:
ssh 出力をログファイルに取得するには、stderr
をリダイレクトする必要があります stdout
へ . 2>&1
を追加することでこれを行うことができます あなたのbashスクリプトの後。
次のようになります:
#!/bin/bash
(
...
) 2>&1 | tee ...
メッセージが正しい順序で表示されない場合は、別のサブシェルを追加してみてください:
#!/bin/bash
((
...
) 2>&1) | tee ...
解決策 3:
私があなたの質問を読んだとき、あなたは出力をログに記録したくはありませんが、コマンドのシーケンス全体をログに記録したくありません。その場合、他の回答は役に立ちません.
-x を指定してシェル スクリプトを呼び出し、すべてを出力します:
sh -x foo.sh
目的のファイルにログを記録します:
sh -x foo.sh >> /home/scripts/cron/logs
解決策 4:
bash では、 set -x
を入れることができます その後、実行するすべてのコマンド (および bash 変数) を出力します。 set +x
でオフにできます .
偏執的になりたい場合は、 set -o errexit
を入力できます あなたのスクリプトで。これは、1 つのコマンドがゼロ以外の終了コードを返した場合、スクリプトが失敗して停止することを意味します。これは、問題が発生したことを通知する UNIX の標準的な方法です。
より良いログを取得したい場合は、ts
を見てください。 moreutils
で debian/ubuntu パッケージ。各行の前にタイムスタンプを付けて出力します。これで、いつ何が起こったかがわかります。
解決策 5:
他の人が言ったことに続いて、セットマニュアルは良いリソースです.私は:
#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x
続けたいスクリプトの先頭、または set -ex
エラー時に終了するかどうか。