解决Linux关闭终端(关闭SSH等)后运行的程序或服务自动停止的问题打开关闭(切断SSH连接)后,发现服务中断,导致网页无法访问。解决方法:使用nohup命令,让程序在关闭窗口(切换SSH连接)时,在后台继续运行。比如在Unix/Linux下,如果想让某个程序在后台运行,很多都是在程序末尾使用&来让程序自动运行。比如我们想在后台运行mysql:/usr/local/mysql/bin/mysqld_safe--user=mysql&但是我们的很多程序并没有像mysqld一样做成守护进程,可能我们的程序只是普通的程序,一般这种程序以&结束,但是如果终端关闭,程序也会关闭。但是为了能够在后台运行,那么我们可以使用nohup命令。比如我们有一个test.php需要后台运行,我们想让它在后台定时运行,那么使用nohup:nohup/root/test.php& 提示: [~]$appendingoutputtonohup.out 好了,证明运行成功,同时将程序运行的输出信息放入当前目录下的nohup.out文件中。nohup命令说明: 用途:不挂断运行命令。 语法:nohupCommand[Arg...][ &] 描述:nohup命令运行由Command参数和任何相关Arg参数指定的命令,忽略所有挂断(SIGHUP)信号。注销后使用nohup命令在后台运行程序。要在后台运行nohup命令,请将&(“和”的符号)添加到命令的末尾。 无论nohup命令的输出是否重定向到终端,输出都会附加到当前目录下的nohup.out文件中。如果当前目录中的nohup.out文件不可写,输出将重定向到$HOME/nohup.out文件。如果无法创建或打开文件进行追加,则不会调用由Command参数指定的命令。如果标准错误是终端,则将指定命令写入标准错误的所有输出重定向到与标准输出相同的文件描述符。 退出状态:命令返回以下退出值: 126Command参数指定的命令可以找到但无法调用。 127nohup命令遇到错误或找不到Command参数指定的命令。 否则,nohup命令的退出状态就是Command参数指定的命令的退出状态。 nohup命令及其输出文件 nohup命令:如果你正在运行一个进程,你觉得当你退出你的账户时,这个进程不会结束,你可以使用nohup命令。该命令可以在你退出账号/关闭终端后继续运行相应的进程。nohup表示不挂断(nohangup)。 这条命令的一般形式是:>nohup命令& 使用nohup命令提交作业 如果使用nohup命令提交作业,那么默认情况下作业的所有输出都是重定向到一个名字为nohup.out的文件中,除非另外指定输出文件:(即自定义输出的文件名) >nohup命令>myout.file2>&1& 中在上面的示例中,输出被重定向到myout.file文件。 使用职位查看职位。 被fg%n 关闭。 另外还有两个常用的ftp工具,ncftpget和ncftpput,可以实现ftp后台上传下载,所以我可以使用这两个命令在后台上传下载文件。思考:问题1为什么关闭ssh后程序就停止运行了?罪魁祸首:SIGHUP信号让我们看看为什么关闭窗口/断开连接会导致正在运行的程序死掉。在Linux/Unix中,有几个概念:进程组(processgroup):一个或多个进程的集合,每个进程组都有一个唯一的进程组ID,即进程组长进程的ID。会话:一个或多个进程组的集合,只有一个会话负责人。会话ID是引导进程的ID。会话可以有一个单一的控制终端。连接到控制终端的会话领导进程称为控制进程。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。根据POSIX.1的定义:挂断信号(SIGHUP)的默认动作是终止程序。当终端接口检测到网络连接断开时,向控制进程(会话领导进程)发送挂断信号。如果会话领导进程终止,这个信号被发送到会话前台进程组。当进程退出并产生孤儿进程组时,如果有孤儿进程组进程处于STOP状态,则向该进程组中的所有进程发送SIGHUP和SIGCONT信号。(参考孤儿进程:http://blog.csdn.net/hmsiwtv/...)结论:因此,当网络断开或终端窗口关闭时,即SSH断开后,控制进程接收到SIGHUP信号并退出。导致会话中的其他进程退出。总之:ssh开启后,bash等就是它的子程序。一旦关闭ssh,系统就会杀掉所有相关进程!!一旦ssh关闭,导致正在执行的任务被取消示例:让我们看一个示例。打开两个SSH终端窗口并在其中一个中运行top命令。[root@tivf09root]#top在另一个终端窗口中,找到top的进程ID为5180,其父进程ID为5128,即登录shell。[root@tivf09root]#ps-ef|greptoproot51805128001:03pts/000:00:02toproot58573672001:12pts/200:00:00greptop使用pstree命令制作itclearer看清楚这个关系:[root@tivf09root]#pstree-H5180|greptop|-sshd-+-sshd---bash---top用ps-xj命令看,loginshell(PID5128)和top在同一个session中,shell是session的第一个进程,它的进程组PGID是5128,top的进程组PGID是5180,是前台进程组。[root@tivf09root]#ps-xj|grep51285126512851285128pts/05180S00:00-bash5128518051805128pts/05180S00:50top36721809518094S3622:0pts/grep/05128关闭第一个SSH窗口,在另一个窗口可以看到top也被kill掉了。[root@tivf09root]#ps-ef|grep5128root186993672004:35pts/200:00:00grep5128问题2为什么打开ssh后守护程序不影响运行,即使ssh是关闭?因为他们的程序比较特殊,比如httpd–kstart运行这个之后,不属于sshd进程组而是一个单独的进程组,所以即使ssh关闭了也没有关系![root@CentOS5-4~]#pstree|grephttp|-httpd[root@CentOS5-4~]#pstree|greptop|-sshd-+-sshd---bash---top结论:守护进程启动了命令本身是特殊的,不同于一般的命令。一旦使用诸如mysqld_safe之类的命令,它将作为守护进程运行。因此,不可能将一个通用程序改造成守护程序。问题三:使用后台运行命令&程序能摆脱ssh进程组的控制吗?即当ssh关闭后,后台程序继续运行?我们来做个实验:find/-name'http'&usectrl+dlogout然后进入系统,你会看到这个命令再运行吗?答案是:命令被中止!!因为它仍然属于这个ssh进程组,所以即使添加了Gotit&也摆脱不了!![root@CentOS5-4~]#pstree|grepfind|-sshd-+-sshd---bash---find结论是:只要是ssh打开执行的通用命令,就是不是守护程序,不管加不加,一旦关闭ssh,系统就会用SIGHUP终止问题。4nohup可以解决问题,但是为了在退出登录后能够在后台运行,那么我们可以使用nohup命令。现在我们开始查找find/-name'*http*'&,想后台运行,那么使用nohup:nohupfind/-name"*httpd*",此时程序运行的输出信息默认是放在当前文件夹的nohup.out文件中,是否加&不会影响这个命令,只是让程序在前台或者后台运行。扩展:linux命令nohup+screen命令如果想在关闭ssh连接后继续运行刚刚启动的程序,可以使用nohup。但是如果你想第二天来的时候查看一下昨天运行的程序的状态,然后继续工作,那么nohup就不行了,需要使用screen来达到这个目的。nohup虽然好用,但还是比较“笨拙”。它可以处理简单的命令,但对于需要人机交互的复杂任务来说就麻烦了。事实上,我们可以使用更强大的实用屏幕。流行的Linux发行版(如RedHatEnterpriseLinux4)通常都带有screen实用程序,如果没有,您可以从GNUscreen的官方网站下载。1)使用屏幕执行,按任意键进入子界面;我是用ping命令开始执行的,如果我下班了,但是想关闭ssh继续运行ping,那么按ctrl+a再按d就可以挂起子界面,会显示[detached],这时我回到了父界面;使用screen–ls查看当前子接口的状态screen-ls在/tmp/screens/S-root中有一个screenon:22292.pts-3.free(Detached)1Socket,这里的22292其实就是pid号子接口;如果你回到子界面使用screen–r22292,你会立即ping子界面;2)如需更多帮助,可以使用C-a(ctrl+a)?查看所有常用的键绑定是:C-a?显示所有键绑定信息C-aw显示所有窗口的列表C-aC-a切换到先前显示的窗口C-ac创建一个运行shell的新窗口并切换到它C-an切换到下一个窗口C-ap切换到上一个窗口(相对于C-an)C-a0..9切换到窗口0..9C-aa发送C-a到当前窗口C-ad暂时断开屏幕会话C-ak杀死当前窗口C-a[进入复制/回滚模式其他常用选项:-cfile使用配置filefileinsteadofdefault$HOME/.screenrc-d|-D[pid.tty.host]不打开新的screensession,而是断开其他正在运行的screensession-hnum指定历史回滚缓冲区的大小为numlines-list|-ls以pid.tty.host的格式列出现有的屏幕会话-d-m在断开连接模式的开始会话中启动一个-rsessionowner/[pid.tty.host]重新连接断开连接的会话。在多用户模式下,需要指定sessionowner和setuid-root权限才能连接到其他用户的screensession。-Ssessionname在创建screensession时为session指定一个名称-v显示screen版本信息-wipe[match]同-list,但删除那些无法连接的session
