如何判断Bash脚本是否在使用nohup运行?

9
我有一个脚本用于处理文件中的记录,通常需要1-2小时。当它在运行时,它会打印正在处理的记录数量。
现在,我的要求是:当它与nohup一起运行时,我不希望它打印进度;只有在手动运行时才应该打印进度。
我的问题是如何知道Bash脚本是否正在使用nohup运行?
假设命令是nohup myscript.sh &。在脚本中,如何从命令行获取nohup?我尝试使用$0,但它给出了myscript.sh
5个回答

9

检查文件重定向不够健壮,因为在脚本中可能已经明确地重定向了标准输入、标准输出和/或标准错误流,此时通常会使用nohup

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

所以,我们真正需要的是一种检测是否忽略 SIGHUP 的方法。在 Linux 中,信号忽略掩码在 /proc/$PID/status 中公开,在 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

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://dev59.com/f2_Xa4cB1Zd3GeqPwg3e#35638712):

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

我不知道为什么这个答案没有得到更多的赞 - 检查$PPID非常简单,对于我的用例来说完美地工作。 - Laurence Renshaw

1
您可以检查STDOUT是否与终端相关:
[ -t 1 ]

4
注意,这检查的是终端是否打开,而不是它是否在nohup下运行。如果您运行myscript.sh > out.txt,此检查也将失败。(我没有给你投反对票) - johndodo

1

一种方法,但并不是非常便携的方法,是在/proc/$$/fd/1上执行readlink,并测试它是否以nohup.out结尾。

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

#!/bin/bash

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

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

[ -t 1 ]

如果你运行 myscript.sh > out.txt,这个检查将会失败。 - ndemou
你能展示一下完整的if/else代码吗? - Petrus Theron

0

谢谢大家。检查STDOUT是个好主意。我刚刚找到了另一种方法。那就是测试tty。 测试tty -s 检查它的返回代码。如果是0,则正在终端上运行;如果是1,则在nohup下运行。


3
实际上,你正在做与tty -s检查标准输出是否为终端相同的事情(参见:http://ss64.com/bash/tty.html),而-t 1也是相同的(参见:http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions)。 - Sorin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接