我有 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&
您能否给我一些提示,我应该做什么才能在后台运行脚本并且仍然在上述两个文件中保留日志?
答案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
每秒一行进入所有 10 个人。我捕捉到一些$info
来自否认的流程并通过以下方式呈现$(command substitution). While ps
仍在报道$pid
我捕获,我知道它仍在运行,所以我sleep.
完成后,所有 10 个文件中的行都将被计数wc.
以这种方式调用进程后,您可以自由地关闭其原始父进程,并且它将继续运行 - 它实际上已被否认。
我认为值得一提的是,该进程实际上最初是在$(command substitution)
和printfs
我的$info
我希望这样我可以有效地控制它。但是一旦它下降终端输出exec 1>&2
(在与 相同的子 shell 中关闭2>&-
),该进程逃脱了,我必须在另一端等待它。有点两全其美,特别是当您使用它来处理输入管道时,只要您能够将注意力集中在所有重定向和进程领导者上。
其他一切都只是为了在这里演示。运行它所需要的只是顶部脚本和:
info="$(($script_path &)2>&- &)"
笔记:这只会将我想要演示的内容精确地打印到终端。正如所指出的$PPID,
该进程被终端拒绝,并且是该进程的直接子进程$PID 1.
答案3
感谢大家的回答。我从他们身上学到了很多东西。问题解决了。 Nohoup 不会干扰记录到外部文件。我的问题的根源很可能是系统性能,因为我正在使用嵌入式 Linux。不知道该怎么办,我重新启动了系统并再次在后台启动脚本。现在可以了。
问题以某种方式解决了,但问题是为什么需要重新启动。