如何规范的把进程放到Linux后台运行

Run program in the background of linux

作为业界多用户操作系统的代表,linux中把一个程序放到后台运行的办法估计连一个只学过3天linux的菜鸟都非常熟悉:

$ ./myApp &

程序已经在前台运行了也没关系,快捷键CTRL-Z,然后键入命令:bg,程序就放入后台执行了。
使用jobs可以列出所有正在后台运行的任务,必要的话,还可以使用fg [pid]把放入后台的任务调度到前台来继续执行。
这样正确吗?没错,至少unix类系统中的手册中都是这样写的。最早的系统也就是这样设计的。
不过自从30多年前开始确立这样的方式之后,操作系统又有了很多发展,其中变化最大的就是安全方面的发展,有很多linux/mac的版本在安全方面又有了新的要求。典型的比如新版的seLinux。
在这些系统中,有些设置就不允许某用户在后台运行程序,这样的就不多说了,请管理员用户修改设置。但更多的可能是这样几种情况:

1.自动杀死用户的后台程序:
这种一般可以使用nohup命令来间接执行用户程序,使用方法为:

$ nohup ./myApp &

这时用户应用一般可以顺利在后台执行,同时后台的输出会重定向到当前目录的nohup.out文件中去,当任务碰到问题,可以参考输出文件的内容进行调试。
2.用户在线的时候后台进程可以顺利执行,用户退出登录后进程被杀死:
这种情况分为两类,一种就是不允许用户退出登录后仍然有进程执行,这时候大多可以用方法1来解决。
还有的情况是,当用户退出后,如果用户进程仍然有输出,而输出所关联的用户终端不存在的话,则被判定为可疑进程,此类可疑进程都会被杀死。这时候可以用如下方法来执行:

#后台运行,忽略所有输出
$ ./myApp > /dev/null 2>&1 &
#后台运行,输出重定向到 myApp.log文件
$ ./myApp > myApp.log 2>&1 &

上面两条执行效果是一样的,只是一个将输出重定向到/dev/null,等于输出被抛弃了。另外一个将输出重定向到了当前目录myApp.log文件。关键需要解释的是最后的2>&1,这表示将标准输出2,也就是stderr错误输出重定向到输出1,也就是stdout标准输出。随后再讲这些捆绑在一起的输出,由stdout标准输出重定向到前面指定的输出文件。
采用这种方法后,后台程序的所有输出都有了输出方向,并不同当前的终端捆绑,这样用户退出登陆后,进程不会被系统杀死。有的时候,方法1、方法2可以结合起来一起用。