我如何知道bash脚本是否与nohup一起运行?

时间:2022-06-29 08:36:42

I have a script to process records in some files, it usually takes 1-2 hours. When it's running, it prints a progress of number of records processed.

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

Now, what I want to do is: when it's running with nohup, I don't want it to print the progress; it should print progress only when it run manually.

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

My question is how do I know if a bash script is running with nohup?

我的问题是如何知道bash脚本是否与nohup一起运行?

Suppose the command is nohup myscript.sh &. In the script, how do I get the nohup from command line? I tried to use $0, but it gives myscript.sh.

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

5 个解决方案

#1


2  

You could check if STDOUT is associated with a terminal:

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

[ -t 1 ]

#2


4  

Checking for file redirections is not robust, since nohup can be (and often is) used in scripts where stdin, stdout and/or stderr are already explicitly redirected.

检查文件重定向是不健全的,因为在已经明确重定向stdin,stdout和/或stderr的脚本中可以(并且经常)使用nohup。

Aside from these redirections, the only thing nohup does is ignore the SIGHUP signal (thanks to this guy for the link.)

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

So, really what we're asking for is a way to detect if SIGHUP is being ignored. In linux, the signal ignore mask is exposed in /proc/$PID/status, in the least-significant bit of the SigIgn hex string.

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

Provided we know the pid of the bash script we want to check, we can use egrep. Here I see if the current shell is ignoring SIGHUP (i.e. is "nohuppy"):

如果我们知道要检查的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

#3


1  

One way, but not really portable would be to do a readlink on /proc/$$/fd/1 and test if it ends with nohup.out.

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

But the traditional approach to such problems is to test if the output is a terminal:

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

[ -t 1 ]

#4


0  

Thank you guys. Check STDOUT is a good idea. I just find another way to do it. That is to test tty. test tty -s check its return code. If it's 0 , then it's running on a terminal; if it's 1 then it's running with nohup.

感谢你们。检查STDOUT是个好主意。我只是找到了另一种方法。那是测试tty。 test tty -s检查其返回码。如果是0,则它在终端上运行;如果它是1然后它与nohup一起运行。

#5


0  

You can either check if the parent pid is 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

or if your script ignores the SIGHUP signal (see https://*.com/a/35638712/1011025):

或者如果您的脚本忽略了SIGHUP信号(请参阅https://*.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

#1


2  

You could check if STDOUT is associated with a terminal:

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

[ -t 1 ]

#2


4  

Checking for file redirections is not robust, since nohup can be (and often is) used in scripts where stdin, stdout and/or stderr are already explicitly redirected.

检查文件重定向是不健全的,因为在已经明确重定向stdin,stdout和/或stderr的脚本中可以(并且经常)使用nohup。

Aside from these redirections, the only thing nohup does is ignore the SIGHUP signal (thanks to this guy for the link.)

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

So, really what we're asking for is a way to detect if SIGHUP is being ignored. In linux, the signal ignore mask is exposed in /proc/$PID/status, in the least-significant bit of the SigIgn hex string.

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

Provided we know the pid of the bash script we want to check, we can use egrep. Here I see if the current shell is ignoring SIGHUP (i.e. is "nohuppy"):

如果我们知道要检查的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

#3


1  

One way, but not really portable would be to do a readlink on /proc/$$/fd/1 and test if it ends with nohup.out.

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

But the traditional approach to such problems is to test if the output is a terminal:

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

[ -t 1 ]

#4


0  

Thank you guys. Check STDOUT is a good idea. I just find another way to do it. That is to test tty. test tty -s check its return code. If it's 0 , then it's running on a terminal; if it's 1 then it's running with nohup.

感谢你们。检查STDOUT是个好主意。我只是找到了另一种方法。那是测试tty。 test tty -s检查其返回码。如果是0,则它在终端上运行;如果它是1然后它与nohup一起运行。

#5


0  

You can either check if the parent pid is 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

or if your script ignores the SIGHUP signal (see https://*.com/a/35638712/1011025):

或者如果您的脚本忽略了SIGHUP信号(请参阅https://*.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