Skip to main content

 路由器设置 > 新闻资讯 >

修复"正确操作nohup让程序始终在后台运行"

2014-05-06 00:41 浏览:


问题:“抚琴煮酒”(余洪春)在《构建高可用Linux服务器(第二版)》的第119页中写到“产生此问题的原因是:虽然Shell中提示了nohup成功,但还是需要按键盘上的任意键退回到Shell输入命令窗口,然后通过在Shell中输入exit来退出终端,而不是每次在nohup执行成功后直接关闭终端。”

解决办法:使用登录shell防止终端关闭而导致进行自动退出的情况。我常用的命令行为:su -l -c "nohup /some/command.sh >/dev/null 2>&1 &" 。

PS:Red Hat/CentOS启动时在后台运行用户命令,可在/etc/rc.local文件中添加如下行:su -l -c "nohup /some/command.sh >/dev/null 2>&1 &"。

解释:

(1)su -lc表示以登录shell(-l)执行(-c)命令;

(2)经过脚本测试nohup 后面跟着的>/dev/null 2>&1只对nohup本身有作用,即很难使用nohup向/some/command.sh 传递参数,这一点还没有找到相关的资料。

什么是登录shell:(1)用户登陆时,输入用户名和密码后启动的shell;(2)通过带--login参数的命令:bash --login而启动的shell,对于用户来说,登陆shell和非登陆shell的主要区别是:启动shell时所执行的startup文件不同。非登陆shell执行的startup文件仅为:~/.bashrc,而登陆shell执行startup文件为:/etc/profile、~/.bash_profile、~/.bashrc。

什么是非登录shell:除了以上两种情况生成的用户对话,如直接运行bash命令,su某一个用户等。

什么是交互shell:一般的用户与Linux系统用命令行进行操作时使用的shell都为交互式shell。

什么是非交互shell:但执行脚本时,shell就工作在非交互式模式下,因为shell从第一条命令执行到最后一条然后退出,不与用户进行任何交互。

以上四个定义可以参阅以下链接:

linux下的bash与sh 详解以及例子

登录shell,交互式非登录shell,非交互式shell

什么是交互式登录 Shell

 

书中原文:

“我的Nginx负载均衡器监控Nginx进程的脚本nginx_pid需要放入后台不间断地运行,所以想用命令/bin/sh/data/nginx_pidsh &来达到此目的,在输入完命令后我就关闭了终端,可再次登录终端时发现此程序并没有运行。忽然想起可能是因为没有使用nohup命令,试了试,果然如此,带上nohup命令后就正常了。   
我们的很多程序只是普通的程序,即使它们使用&结尾,如果终端关闭,那么程序也会被关闭。为了能够在后台运行,我们需要使用nohup这个命令,原程序的标准输出被自动改到当前目录下的nohupout文件里,起到了log的作用。    
但是有时候这样做会有问题:如果把终端关闭,进程也会被自动关闭。查看nohupout可以看到在关闭终端的瞬间服务自动关闭了。    
产生此问题的原因是:虽然Shell中提示了nohup成功,但还是需要按键盘上的任意键退回到Shell输入命令窗口,然后通过在Shell中输入exit来退出终端,而不是每次在nohup执行成功后直接关闭终端。    
这个错误许多朋友(包括我)容易忽视,希望大家在工作中注意。”

扩充:

在nohup的手册中有一段话需要认真体会“If standard  input is a terminal, redirect it from /dev/null.  If standard output is a terminal, append output to ‘nohup.out’ if possible, ‘$HOME/nohup.out’ otherwise.  If standard error is a terminal, redirect it to standard output.  To save output to FILE, use ‘nohup COMMAND > FILE’.”。

什么是标准输入?什么是标准输出?什么是标准错误输出?这些问题都比较回答。可以参阅以下链接:

linux shell数据重定向(输入重定向与输出重定向)详细分析

Linux shell的标准输入、输出和错误

但“哪些操作或设备被认为是标准输入,哪些操作或设备被认为是标准输出”这两个问题不怎么好回答。从上面那段话可以看出终端既是一种标准输入设备又是一种标准输出设备(文字中提到的“终端”我认为只是用户的字符界面样式的屏幕而已。)。根据我的理解标准输入只能来自用户的输入(input)操作,可以认为所有的输入设备都是标准的输入,标准输出对应所有的输出设备如屏幕打印机等,重定向只是将不同的标准输入输出从这些寻常的途径变为用户指定了的途径罢了(改变了标准输入输出)。