Linux 下的进程持久化

本文只介绍:使用“&”,nohup,sudo -b 命令,使进程一直在后台运行的方法。这些命令,对想要在 Linux 上运行小型网络服务器,但不想学习 Supervisor 和 Docker 之类的人,可能会有用。

Linux 下的 & 命令

假设服务器叫 a.out 好了。输入:

user@host $ ./a.out

就可以让 a.out 运行起来。但是这样的话,命令行会一直卡在那里。因为这是服务器,是要跑三五年的。如果想让 a.out 在后台运行,该怎么办呢?方法是输入:

user@host $ ( ./a.out >/dev/null 2>/dev/null ) &
user@host $

多加了个“&”符号,顺便还把 a.out 的输出重定向到 null 了。注意:小括号附近最好加上空格!加“&”的作用,就是让程序移到后台去跑。但是,不在前台跑的程序,显然是不能把东西输出到命令行的,所以要把输出重定向到别的地方。定到日志文件里,比如:

user@host $ ( ./a.out >./stdout.log 2>./stderr.log ) &
user@host $

就更好了。

新的命令:nohup

但是,这样的话,如果一关掉终端,或者,如果是用 ssh 登录到远程的机子上后关闭了 ssh,服务器也会随之退出(程序收到 SIGHUP 信号,但又没有设置忽略)。那怎么样,才能让程序在终端关闭之后,不至于退出呢?一个简单的方法就是使用 nohup 命令。比如:

user@host $ ( nohup ./a.out >./stdout.log 2>./stderr.log ) &
user@host $

这样,终端关闭之后,程序便可以依旧运行了。

如果需要 root 权限……

但是,仍有问题。想象一下,这个服务器:a.out,是一个 HTTP 服务器,它要监听机器的 80 号端口。这样的话,想要运行程序,就必须要 root 权限。怎么办呢?

如果是这样——

user@host $ ( nohup sudo ./a.out >./stdout.log 2>./stderr.log ) &
user@host $

的话,你会发现,服务器并没有跑起来。原因很简单:sudo 一直在等你输密码,但是它在后台等待,而你却在前台,无法输入。

解决方法:使用 sudo 的 -b 参数:

user@host $ sudo -b ./a.out 1>./std.log 2>./err.log
user@host $ Type the password:
user@host $

“-b”参数能使 a.out 自动在后台运行,十分省事情。注意:这里不需要小括号。

参考

《Go语言小贴士4——后台运行》

user@host $ man nohup
user@host $ man sudo
← 毛毛虫 LeetCode (4) Find Median in Two Sorted Arrays →