バックグラウンドでの処理中に複数のファイルにログを記録する

バックグラウンドでの処理中に複数のファイルにログを記録する

2つのログファイルに並列に書き込むbashスクリプトがあります。

echo "$(date) | [STATE] Activating IP forwarding" >> $logsPath$logFileName
echo $(date +"%Y-%m-%d %H:%M")","$previousState >> $logsPath$usageStatsFileName
echo $(date +"%Y-%m-%d %H:%M")","$currentState >> $logsPath$usageStatsFileName

スクリプトをフォアグラウンドで実行すると正常に動作しますが、バックグラウンドで送信するとこのファイルには何も記録されません。

nohup nice ./rfid_reader.sh&

バックグラウンドでスクリプトを実行し、上記の2つのファイルのログを保持し続けるにはどうすればよいですか?

答え1

重要なヒント:

これはほとんど確かに質問とは関係ありません。他の人に役立つ可能性があるので、ここに残しておきます。しかし、少なくとも私が使用しているnohupDebianバージョンでは、内部リダイレクトは影響を受けず、スクリプトnohupのstderrとstdoutのみをキャプチャします。


デフォルトでは、nohupすべての出力はに印刷されますnohup.out。通常これを通知しますが、バックグラウンドで実行されているため表示されません。たとえば、次のことを試してみてください。

$ nohup echo "foo"
nohup: ignoring input and appending output to ‘nohup.out’

これを防ぐには、プログラム出力を明示的にリダイレクトする必要があります。

$ nohup echo "foo" > bar
nohup: ignoring input and redirecting stderr to stdout

したがって、スクリプトを実行してその出力をリダイレクトする必要があります。標準エラーと標準出力ストリームの両方が同じファイルにリダイレクトされます。

nohup nice ./rfid_reader.sh > output_file &

これは実際にはnohupの合理的なデフォルトです。全体的な目的は、ターミナルセッションを閉じてバックグラウンドで実行されるようにすることであるため、ターミナルに印刷するとその目的が失われるためです。

答え2

君は本当に必要ないnohupわかりました。実際、私は個人的にその用途を見つけることができませんでした。

( ./rfidreader.sh 1>&2 & ) 2>&- &

これにより、プロセスが端末から切り離され、何をすべきかを継続し、問題が発生するのを防ぎます。

デモスクリプト

cat <<-\DEMO >|${s=/tmp/script} 
printf 'tty is %s\nparent pid is %s\npid is pid=%s\n' \
     "$(tty)" "$PPID" "$$"
exec 1>&2 ; nums=$(seq 0 9)
rm ${files=$(printf "/tmp/file%s\n" $nums)}
for n in $nums ; do { for f in $files ; do
    echo "Line $n" >>"$f" ; done
sleep 1 ; } ; done
#END
DEMO

デモの実行

s=/tmp/script ;chmod +x $s ;info="$(($s &)2>&- &)"
echo "$info" ; pid="${info##*=}" ; echo
while ps -p $pid >/dev/null ; do sleep 3 ; done
for f in /tmp/file[0-9] ; do
    printf 'path : %s\tline count : %s\n' \
        $f $(<$f wc -l)
done

出力:

tty is not a tty
parent pid is 1
pid is 12123

path : /tmp/file0    line count : 10
path : /tmp/file1    line count : 10
path : /tmp/file2    line count : 10
path : /tmp/file3    line count : 10
path : /tmp/file4    line count : 10
path : /tmp/file5    line count : 10
path : /tmp/file6    line count : 10
path : /tmp/file7    line count : 10
path : /tmp/file8    line count : 10
path : /tmp/file9    line count : 10

上記で証明されています。というファイルをビルドして実行します。/tmp/script chmod~の実行可能ファイルとして提供され、次の形式で提供されます。&backgroundの一つ&backgrounded ( subshell )

スクリプトrms /tmp/file0-910個のファイルとechoes毎秒1行が10人すべてに渡されます。私は少し捕まった。$info拒否から流れ出て提示される。$(command substitution). While psまだ見ています$pidキャプチャしましたが、まだ実行中であることを知っているのでsleep.完了すると、10個のファイルすべての行が計算されます。wc.

この方法でプロセスを呼び出した後は、元の親プロセスを自由に閉じることができ、引き続き実行されます。事実上拒否されます。

プロセスが実際に始まったことは言及する価値があると思います。$(command substitution)そしてprintfs私のもの$infoこのように効果的に制御できることを願っています。しかし、端末出力が落ちたらexec 1>&2(と同じサブシェルで閉じる2>&-)、プロセスが終了し、反対側でこれを待つ必要があります。特に、すべてのリダイレクトとプロセスリーダーに集中できる限り、入力パイプを処理するために使用する場合、両方の世界で最高です。

他のすべてはここでデモンストレーションのためのものです。これを実行するために必要なのは、トップレベルのスクリプトと次のものです。

info="$(($script_path &)2>&- &)"    

メモ:これは私が見たいものだけを端末に印刷します。指摘したとおり$PPID,プロセスは端末によって拒否され、このプロセスの直系サブプロセスです。$PID 1.

答え3

みんなの回答ありがとうございます。私はそれらから多くを学びました。問題が解決しました。 Nohoupは外部ファイルへのロギングを妨げません。私の問題の原因は組み込みLinuxを使用しているため、システムのパフォーマンスである可能性が高いです。何をすべきかわからないので、システムを再起動し、バックグラウンドでスクリプトを再起動しました。今大丈夫です。

問題は何とか解決されたが、なぜ再起動が必要なのか疑問でした。

関連情報