我有一个脚本来处理某些文件中的记录,通常需要1-2个小时。当它运行时,它会打印处理过的记录数量的进度。
现在,我想要做的是:当它与nohup
一起运行时,我不希望它打印进度;它应该只在手动运行时打印进度。
我的问题是如何知道bash脚本是否与nohup
一起运行?
假设命令为nohup myscript.sh &
。在脚本中,如何从命令行获取nohup
?我尝试使用$0
,但它提供了myscript.sh
。
答案 0 :(得分:8)
检查文件重定向是不健全的,因为nohup
可以(通常是)在stdin,stdout和/或stderr已被明确重定向的脚本中使用。
除了这些重定向外,nohup
唯一做的就是ignore the SIGHUP
signal(感谢Blrfl链接。)
因此,我们真正要求的是一种检测SIGHUP
是否被忽略的方法。在linux中,信号忽略掩码在/proc/$PID/status
,in the least-significant bit of the SigIgn
hex string中公开。
如果我们知道要检查的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 :(得分:1)
您可以检查STDOUT是否与终端关联:
[ -t 1 ]
答案 2 :(得分: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 ]
答案 3 :(得分:0)
谢谢你们。检查STDOUT是个好主意。我只是找到了另一种方法。那是测试tty。 test tty -s检查其返回码。如果它是0,那么它在终端上运行;如果它是1然后它正在运行nohup。
答案 4 :(得分:0)
您可以检查父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