因为各类缘由,须要经过ssh登陆linux或者unix主机,不少时候咱们须要经过ssh的终端启动一 些服务或者运行一些程序,可是默认状况下,当咱们关闭ssh终端链接,随之启动的程序也会关闭。缘由是:SSH会话关闭时,ssh所关联的pty关闭,系 统会给这个pty所关联的session中的全部进程发送SIGHUP信号,SIGHUP的默认信号处理程序是终止进程,除非进程本身处理了 SIGHUP。html
解决方法以下:mysql
使用现成的命令nohup,可让指定的程序在pty关闭以后继续运行。linux
运行方法:sql
#nohup program &shell
如今就能够正常关闭ssh了,你会发现你的服务依然存在运行编程
当SecureCRT异常关闭后,后台进程一同关闭的现象罪魁祸首 Signup信号
做者: 2hei 发表于2009年5月19日 22:24 版权声明: 能够转载, 转载时务必以超链形式标明文章原始出处和做者信息及版权声明 http://www.2hei.net/mt/2009/05/securecrt-closed-and-sighup.html
症状:使用SecureCRT工具ssh远程链接linux,不退出ssh,而是强行关闭终端(合上笔记本走人)状况下,后台启动的应用也会关闭。
后果:男人哭吧哭吧不是罪!
测试案例:
很明显的是关闭终端后,前台运行的程序会被随之关闭,可是后台进程也会由于终端异常关闭而关掉,以下是一个简单的测试结果:
一、后台执行程序,正常关闭ssh链接,关闭终端的状况:
开启两个终端,其中第一个在后台执行ping操做
ping google.com | tee log.txt &
在第二个终端观察
tail -f log.txt 能够看到日志一直在写
使用pstree命令能够看到ping的进程存在
|-sshd-+-sshd---sshd---bash---pstree
| `-sshd---sshd---bash-+-ping
| `-tee
Ctrl+D 退出第一个终端 而后关闭终端
第二个终端的日志仍然在写,pstree命令:
|-ping
ps x
29427 ? S 0:00 ping google.com
看到ping的进程依然存在
二、后台执行程序,非正常关闭ssh链接(模拟忽然掉电或者,将来得及退出ssh,或者ssh仍然链接,直接关闭终端SecureCRT)状况:
一样开启两个终端,其中第一个在后台执行ping操做
ping google.com | tee log.txt &
在第二个终端观察
tail -f log.txt 能够看到日志一直在写
使用pstree命令能够看到ping的进程存在
|-sshd-+-sshd---sshd---bash---pstree
| `-sshd---sshd---bash-+-ping
| `-tee
在不退出ssh的状况下,强行关闭第一个终端(SecureCRT)
在第二个终端观察
tail -f log.txt 能够看到日志已经中止写。
使用pstree命令能够看到ping的进程被停掉
ps aux看不到ping的进程,说明强行关闭终端的状况下后台进程也别kill掉了
查了一下资料,这其中起关键的是 SIGHUP信号
查看全部的信号:
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1
36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5
40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5
60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1
64) SIGRTMAX
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称作可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会形成信号丢失,然后者不会。
SIGHUP信号在用户终端链接(正常或非正常)结束时发出, 一般是在终端的控制进程结束时, 通知同一session内的各个做业, 这时它们与控制终端再也不关联。
登陆Linux时,系统会分配给登陆用户一个终端(Session)。在这个终端运行的全部程序,包括前台进程组和后台进程组,通常都属于这个 Session。
当用户退出Linux登陆时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操做为终止进程,所以前台进程组和后台有终端输出的进程就会停止。
不过有的程序能够捕获这个信号,并忽略它,这样就算退出了Linux登陆,后台程序依旧运行。
此外,对于与终端脱离关系的守护进程,这个信号用于通知它从新读取配置文件。
如下是网络的相关资料
http://hi.baidu.com/xingfengsoft/blog/item/fedbd05c4d8c7e45faf2c0c8.html
—— secureCRT异常退出和执行exit的区别?
若是直接关闭secureCRT(此处假设是使用ssh登陆终端的),那么对于被登陆的系统来讲,就是远端程序异常断连。和咱们忽然断网掉线是同样的效果。
这 种状况下,用户并无信号发送,而是sshd服务检测到对端响应超时,而后向以前创建起的链接以及该链接下(ssh登陆后会分配一个bash给用户)的进 程发送结束信号。若是部分进程忽略sshd发送的信号,进程不退出,在分配给用户的bash退出后,该进程将被init进程接管。
终端异常退出后,后台进程不关闭的解决办法:
一、使用nohup命令: nohup <command> [argument…] & nohup能够屏蔽SIGHUP信号!
二、使用 screen命令。
简单介绍以下:
SCREEN vi /tmp/2hei.net
须要中断链接:
screen Ctrl+a d
查询screen进程:
ps x
20377 ? Ss 0:00 SCREEN vi /tmp/2hei.net
重连 screen -r 20377
参考资料:
http://www.ibm.com/developerworks/cn/linux/l-cn-screen
Linux Jobs等先后台运行命令解
A,Shell支持做用控制,有如下命令:
1. command& 让进程在后台运行
2. jobs 查看后台运行的进程
3. fg %n 让后台运行的进程n到前台来
4. bg %n 让进程n到后台去;
PS:"n"为jobs查看到的进程编号.
B.下列转:http://blog.chinaunix.net/u/1604 /showart_1079559.html
fg、bg、jobs、&、ctrl + z都是跟系统任务有关的,虽然如今基本上不怎么须要用到这些命令,但学会了也是很实用的
一。& 最常常被用到
这个用在一个命令的最后,能够把这个命令放到后台执行
二。ctrl + z
能够将一个正在前台执行的命令放到后台,而且暂停
三。jobs
查看当前有多少在后台运行的命令
四。fg
将后台中的命令调至前台继续运行
若是后台中有多个命令,能够用 fg %jobnumber将选中的命令调出,%jobnumber是经过jobs命令查到的后台正在执行的命令的序号(不是pid)
五。 bg
将一个在后台暂停的命令,变成继续执行
若是后台中有多个命令,能够用bg %jobnumber将选中的命令调出,%jobnumber是经过jobs命令查到的后台正在执行的命令的序号(不是pid)
#Linux下使用Shell命令控制任务 Jobs执行
下列命令能够用来操纵进程任务:
ps 列出系统中正在运行的进程;
kill 发送信号给一个或多个进程(常常用来杀死一个进程);
jobs 列出当前shell环境中已启动的任务状态,若未指定jobsid,则显示全部活动的任务状态信息;若是报告了一个任务的终止(即任务的状态被标记为 Terminated),shell 从当前的shell环境已知的列表中删除任务的进程标识;
bg 将进程搬到后台运行(Background);
fg 将进程搬到前台运行(Foreground);
将job 转移到后台运行
若是你常常在X图形下工做,你可能有这样的经历:经过终端命令运行一个GUI程序,GUI界面出来了,可是你的终端还停留在原地,你不能在shell中继续执行其余命令了,除非将GUI程序关掉。
为了使程序执行后终端还能继续接受命令,你能够将进程移到后台运行,使用以下命令运行程序: #假设要运行xmms
$xmms &
这样打开xmms后,终端的提示又回来了。如今xmms在后台运行着呢;但万一你运行程序时忘记使用“&”了,又不想从新执行;你能够先使用ctrl+z挂起程序,而后敲入bg命令,这样程序就在后台继续运行了。
概念:当前任务
若是后台的任务号有2个,[1],[2];若是当第一个后台任务顺利执行完毕,第二个后台任务还在执行中时,当前任务便会自动变成后台任务号码 “[2]”的后台任务。因此能够得出一点,即当前任务是会变更的。当用户输入“fg”、“bg” 和“stop”等命令时,若是不加任何引号,则所变更的均是当前任务。
察看jobs
使用jobs或ps命令能够察看正在执行的jobs。
jobs命令执行的结果,+表示是一个当前的做业,减号表是是一个当前做业以后的一个做业,jobs -l选项可显示全部任务的PID,jobs的状态能够是running, stopped, Terminated,可是若是任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识;也就是说,jobs命令显示的是当前shell环境中所起的后台正在运行或者被挂起的任务信息;
进程的挂起
后台进程的挂起:
在solaris中经过stop命令执行,经过jobs命令查看job号(假设为num),而后执行stop %num;
在redhat中,不存在stop命令,可经过执行命令kill -stop PID,将进程挂起;
当要从新执行当前被挂起的任务时,经过bg %num 便可将挂起的job的状态由stopped改成running,仍在后台执行;当须要改成在前台执行时,执行命令fg %num便可;
前台进程的挂起:
ctrl+Z;
进程的终止
后台进程的终止:
方法一:
经过jobs命令查看job号(假设为num),而后执行kill %num
方法二:
经过ps命令查看job的进程号(PID,假设为pid),而后执行kill pid
前台进程的终止:
ctrl+c
kill的其余做用
kill除了能够终止进程,还能给进程发送其它信号,使用kill -l 能够察看kill支持的信号。
SIGTERM是不带参数时kill发送的信号,意思是要进程终止运行,但执行与否还得看进程是否支持。若是进程尚未终止,可使用kill -SIGKILL pid,这是由内核来终止进程,进程不能监听这个信号。
===================
Unix/Linux下通常想让某个程序在后台运行,不少都是使用 & 在程序结尾来让程序自动运行。好比咱们要运行mysql在后台:
/usr/local/mysql/bin/mysqld_safe --user=mysql &
可是咱们不少程序并不象mysqld同样能够作成守护进程,可能咱们的程序只是普通程序而已,通常这种程序即便使用 & 结尾,若是终端关闭,那么程序也会被关闭。为了可以后台运行,咱们须要使用nohup这个命令,好比咱们有个start.sh须要在后台运行,而且但愿在 后台可以一直运行,那么就使用nohup:
nohup /root/start.sh &
在shell中回车后提示:
[~]$ appending output to nohup.out
原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了log的做用。
可是有时候在这一步会有问题,当把终端关闭后,进程会自动被关闭,察看nohup.out能够看到在关闭终端瞬间服务自动关闭。
咨询红旗Linux工程师后,他也不得其解,在个人终端上执行后,他启动的进程居然在关闭终端后依然运行。
在 第二遍给我演示时,我才发现我和他操做终端时的一个细节不一样:他是在当shell中提示了nohup成功后还须要按终端上键盘任意键退回到shell输入 命令窗口,而后经过在shell中输入exit来退出终端;而我是每次在nohup执行成功后直接点关闭程序按钮关闭终端.。因此这时候会断掉该命令所对 应的session,致使nohup对应的进程被通知须要一块儿shutdown。
这个细节有人和我同样没注意到,因此在这儿记录一下了。
附:nohup命令参考
nohup 命令
用途:不挂断地运行命令。
语法:nohup Command [ Arg ... ] [ & ]
描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略全部挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示"and"的符号)到命令的尾部。
不管是 否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。若是当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。若是没有文件能建立或打开以用于追加,那么 Command 参数指定的命令不可调用。若是标准错误是一个终端,那么把指定的命令写给标准错误的全部输出做为标准输出重定向到相同的文件描述符。
退出状态:该命令返回下列出口值:
126 能够查找但不能调用 Command 参数指定的命令。
127 nohup 命令发生错误或不能查找由 Command 参数指定的命令。
不然,nohup 命令的退出状态是 Command 参数指定命令的退出状态。
nohup命令及其输出文件
nohup命令:若是你正在运行一个进程,并且你以为在退出账户时该进程还不会结束,那么可使用 nohup命令。该命令能够在你退出账户/关闭终端以后继续运行相应的进程。nohup就是不挂起的意思( n ohang up)。
该命令的通常形式为:nohup command &
使用nohup命令提交做业
若是使用nohup命令提交做业,那么在缺省状况下该做业的全部输出都被重定向到一个名为 nohup.out的文件中,除非另外指定了输出文件:
nohup command > myout.file 2>&1 &
在上面的例子中,输出被重定向到myout.file文件中。
使用 jobs 查看任务。
使用 fg %n 关闭。
另外有两个经常使用的ftp工具ncftpget和ncftpput,能够实现后台的ftp上传和下载,这样就能够利用这些命令在后台上传和下载文件了。
简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后台运行,若是启动该程序的控制台logout,则该进程随即终止。
要实现守护进程,一种方法是按守护进程的规则去编程(本站有文章介绍过),比较麻烦;另外一种方法是仍然用普通方法编程,而后用nohup命令启动程序:
nohup<程序名>&
则控制台logout后,进程仍然继续运行,起到守护进程的做用(虽然它不是严格意义上的守护进程)。
使用nohup命令后,原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了 log的做用,实现了完整的守护进程功能。
ygwu @ 2005年04月18日 上午10:03
For example:
如何远程启动WebLogic服务?
用telnet远程控制服务器,远程启动WEBLOGIC服务,启动后关闭 telnet,WebLogic服务也跟着中止,这是由于使用telnet启动的进程会随着telnet进程的关闭而关闭。因此咱们可使用一些UNIX 下的命令来作到不关闭。
使用以下命令:
nohup startWeblogic.sh&
若是想要监控标准输出可使用:
tail -f nohup.out
当在后台运行了程序的时候,能够用jobs命令来查看后台做业的状态。在有多个后台程序时,要使用来参数的fg命令将不一样序号的后台做业切换到前台上运行。
当用户启动一个进程的时候,这个进程是运行在前台,使用与相应控制终端相联系的标准输入、输出进行输入和输出。即便将进程的输入输出重定向,并将进程放 在后台执行,进程仍然和当前终端设备有关系。正由于如此,在当前的登陆会话结束时,控制终端设备将和登陆进程相脱离,那么系统就向全部与这个终端相联系的 进程发送SIGHUP的信号,通知进程线路已经挂起了,若是程序没有接管这个信号的处理,那么缺省的反应是进程结束。所以普通的程序并不能真正脱离登陆会 话而运行进程,为了使得在系统登陆后还能够正常执行,只有使用命令nohup来启动相应程序。
使用命令nohup固然能够启动这样的程序,但 nohup启动的程序在进程执行完毕就退出,而常见的一些服务进程一般永久的运行在后台,不向屏幕输出结果。在Unix中这些永久的后台进程称为守护进程 (daemon)。守护进程一般从系统启动时自动开始执行,系统关闭时才中止。
在守护进程中,最重要的一个是超级守护进程inetd,这个进 程接管了大部分网络服务,但并非对每一个服务都本身进行处理,而是依据链接请求,启动不一样的服务程序与客户机打交道。inetd支持网络服务种类在它的设 置文件/etc/inet.conf中定义。inet.conf文件中的每一行就对应一个端口地址,当inetd接受到链接这个端口的链接请求时,就启动 相应的进程进行处理。使用inetd的好处是系统没必要启动不少守护进程,从而节约了系统资源,然而使用inetd启动守护进程相应反应会迟缓一些,不适合 用于被密集访问的服务进程
bash