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
重要なヒント:
これはほとんど確かに質問とは関係ありません。他の人に役立つ可能性があるので、ここに残しておきます。しかし、少なくとも私が使用しているnohup
Debianバージョンでは、内部リダイレクトは影響を受けず、スクリプト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-9
10個のファイルと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を使用しているため、システムのパフォーマンスである可能性が高いです。何をすべきかわからないので、システムを再起動し、バックグラウンドでスクリプトを再起動しました。今大丈夫です。
問題は何とか解決されたが、なぜ再起動が必要なのか疑問でした。