前言
Linux因其出色的稳定性与内存管理机制,非常适合运行不间断服务。
然而熟悉ssh的用户会发现,即使用& 中断连接后用户程序也会退出,不够人性化。
查阅
不想开着ssh傻等就需要掌握不间断运行程序的方法:
多数资料给出的解决方案是screen
深入了解会发现nohup
也可以实现
开源项目更青睐start-stop-daemon
解决
同样是后台运行,有什么区别呢?
区别
screen
先说screen因为他的机制是三者中完全不同的:
Screen is a terminal multiplexer, or more accurately a terminal-window manager.
这个解释的比较明白了,screen本质上只是多开终端,通过detach断开终端与当前tty的连接(类似于将全屏窗口最小化)。
终端均由screen派生且相互独立,因此只要screen存活,终端内程序运行不受影响。
可以看出,ssh的bash与screen的bash相互独立,互不影响。但后台程序sleep依然受到所在的bash影响,无法独立存在。
nohup
再来看nohup的机制
Nohup is a program that lets you run a program on a remote server without having to worry about whether you ssh session hangs up or not.
这个说法没毛病,我们知道linux终端为程序提供了人机交互,程序标准输入输出经由终端呈现给用户,同时终端也会在退出时时向会话程序发送SIGHUP挂断信号。
想改变程序与终端“共存亡”的局面,就要用nohup让程序忽略SIGHUP信号继续执行。当然,没有终端提供标准输入输出,还需要一些特殊处理。
后台程序通常设计为运行时不需要接受标准输入(如提供web服务),而输出则可通过nohup定向到文件,默认为当前目录下的./nohup.out无权限则改为~/nohup.out
注意nohup命令本身并无后台含义,直接执行仍会占用终端,故常与&连用,如nohup sleep 100 >/dev/null 2>&1 &
可以看出,目前sleep还是派生于bash的子进程,随后中断当前会话重新登陆。
本应随bash一同结束的sleep由于忽略了SIGHUP变为孤儿进程,进而被init接管,继续运行。
start-stop-daemon
这个放在最后,因为涉及到daemon守护进程的概念。
Daemon程序,又称为守护进程,通常在系统后台长时间运行,由于没有控制终端而无法与前台交互,Daemon程序一般作为系统服务使用。
可以看出daemon已经完全脱离了终端,跟随系统启停。类Debian系统提供了start-stop-daemon对守护进程进行管理。
这里依然使用sleep进行测试,执行 start-stop-daemon -Sqb -x /bin/sleep 100
简单解释参数S=start q=quiet b=background x=exec
很明显sleep直接由init派生,自然不会受到用户bash的任何影响。
另外start-stop-daemon还有很多高级用法,可以指定运行用户,运行路径,操作PID等,具体用法看自带帮助文档。
结论
三种命令都可以实现不中断后台执行的效果,但原理各不相同。
从日常使用出发:
满足断开ssh程序不挂机的需求nohup+&
作为start-stop-daemon
的简单替代完全可以胜任。
对于有交互需求的程序更推荐screen
可以清楚知道离开会话都发生了什么。
类似定时脚本或web服务则建议用start-stop-daemon
控制执行用户权限与复杂参数传递。
参考
terminal - nohup vs screen -- which is better for long running process? - Stack Overflow
daemon_百度百科
start-stop-daemon(8) — Linux manual page