假设我们需要运行应用程序screen
并在screen
退出时保持其运行。以下命令可以完成这项工作,但前提是sleep 1
附加了“”。为什么没有“”就不起作用sleep 1
?
screen -d -m -L sh -c 'DISPLAY=:0 nohup zenity --info --text test >/dev/null 2>/dev/null &'
答案1
这似乎是一个时间问题,因为在nohup
其中一位父母发出信号之前没有足够的时间来禁用信号。您可以通过在命令strace -o /tmp/s -ff
前面添加screen
然后在/tmp/s.*
您看到的日志文件之一中添加来看到这一点
...
access("/bin/nohup", X_OK) = 0
stat("/bin/nohup", {st_mode=S_IFREG|0755, st_size=36696, ...}) = 0
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
+++ killed by SIGHUP +++
您可以简化启动过程。这对我有用,不需要&
.
DISPLAY=:0 screen -d -m -L nohup zenity --info --text test
另一个解决方案似乎是要求父 shell 使用作业控制。这似乎使它要么禁用 SIGHUP 到后台,要么等待子进程nohup
继续前进,然后再退出。使用sh -cm
而不是sh -c
原来的命令应该效果更好。例如,这对我有用
screen -d -m -L sh -cm 'nohup zenity --info --text test >&/dev/null & echo'
而-c
版本则不然。如果使用作业控制,bash
有一个disown
命令可以保护后台作业免受 SIGHUP 的影响,但即使没有,您似乎也不需要它,nohup
因为这也可以工作,无需让screen
进程保持运行:
screen -d -m -L sh -cm 'zenity --info --text test >&/dev/null </dev/null & echo'
答案2
使用nohup
as 包罗万象的命令是不可能的,因为它不允许在nohup.out
不抑制所有输出的情况下摆脱,并且使用nohup.out
代替screenlog.0
是不可能的,因为nohup.out
不保留回车符。
不使用nohup
,而是使用 shell 的trap
.因此,OP中的命令变为:
screen -d -m -L sh -c 'trap "" HUP; DISPLAY=:0 zenity --info --text test >/dev/null 2>/dev/null &'