9

我有一个脚本来处理某些文件中的记录,通常需要 1-2 小时。当它运行时,它会打印处理的记录数的进度。

现在,我想做的是:当它运行时nohup,我不希望它打印进度;它应该仅在手动运行时打印进度。

我的问题是如何知道 bash 脚本是否正在运行nohup

假设命令是nohup myscript.sh &。在脚本中,如何获取nohupfrom 命令行?我尝试使用$0,但它给出了myscript.sh.

4

5 回答 5

9

检查文件重定向并不可靠,因为nohup可以(并且经常)在标准输入、标准输出和/或标准错误已经明确重定向的脚本中使用。

除了这些重定向之外,唯一要做的nohup就是忽略SIGHUP信号(感谢Blrfl的链接。)

所以,我们真正需要的是一种检测是否SIGHUP被忽略的方法。/proc/$PID/status在 linux 中,信号忽略掩码暴露在hex 字符串的最低有效位中SigIgn

如果我们知道要检查的 bash 脚本的 pid,我们可以使用egrep. 在这里,我查看当前 shell 是否忽略SIGHUP(即“nohuppy”):

$ egrep -q "SigIgn:\s.{15}[13579bdf]" /proc/$$/status && echo nohuppy || echo normal
normal
$ nohup bash -c 'egrep -q "SigIgn:\s.{15}[13579bdf]" /proc/$$/status && echo nohuppy || echo normal'; cat nohup.out
nohup: ignoring input and appending output to `nohup.out'
nohuppy
于 2016-02-25T21:28:55.983 回答
1

您可以检查 STDOUT 是否与终端相关联:

[ -t 1 ]
于 2013-02-28T16:50:19.873 回答
1

一种方法,但不是真正可移植的,是做一个 readlink/proc/$$/fd/1并测试它是否以 nohup.out 结尾。

假设您在pts0终端上(并不真正相关,只是为了能够显示结果):

#!/bin/bash

if [[ $(readlink /proc/$$/fd/1) =~ nohup.out$ ]]; then
    echo "Running under hup" >> /dev/pts/0
fi

但解决此类问题的传统方法是测试输出是否为终端:

[ -t 1 ]
于 2013-02-28T17:00:57.353 回答
1

您可以检查父 pid 是否为 1:

if [ $PPID -eq 1 ] ; then
    echo "Parent pid=1  (runing via nohup)" 
else
    echo "Parent pid<>1 (NOT running via nohup)"                                             
fi

或者如果您的脚本忽略 SIGHUP 信号(请参阅https://stackoverflow.com/a/35638712/1011025):

if egrep -q "SigIgn:\s.{15}[13579bdf]" /proc/$$/status ; then
    echo "Ignores SIGHUP (runing via nohup)" 
else
    echo "Doesn't ignore SIGHUP (NOT running via nohup)"                                             
fi
于 2017-08-17T17:29:30.143 回答
0

谢谢你们。检查 STDOUT 是个好主意。我只是找到另一种方法来做到这一点。也就是测试tty。test tty -s 检查它的返回码。如果它是 0 ,那么它在终端上运行;如果它是 1,那么它使用 nohup 运行。

于 2013-02-28T17:09:14.817 回答