nohup命令浅析

来源:互联网 发布:淘宝上靠谱的韩代店 编辑:程序博客网 时间:2024/04/29 03:22

要将一个命令放到后台执行,我们一般使用nohup sh command &
&都知道是放到后台执行这个命令,那么nohup是做什么的?
这就要从unix的信号说起,unix的信号机制可以说进程间通信的一种,进程间可以通过发送信号来完成某些特定的动作,比较熟悉就是kill -9 pid
先看linux有哪些信号:
[root@limt ~]# 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
16) SIGSTKFLT 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


[root@limt ~]# more /usr/include/bits/signum.h
#define SIGHUP 1 /* Hangup (POSIX). */
#define SIGINT 2 /* Interrupt (ANSI). */
#define SIGQUIT 3 /* Quit (POSIX). */
#define SIGILL 4 /* Illegal instruction (ANSI). */
#define SIGTRAP 5 /* Trace trap (POSIX). */
#define SIGABRT 6 /* Abort (ANSI). */
#define SIGIOT 6 /* IOT trap (4.2 BSD). */
#define SIGBUS 7 /* BUS error (4.2 BSD). */
#define SIGFPE 8 /* Floating-point exception (ANSI). */
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
#define SIGSEGV 11 /* Segmentation violation (ANSI). */
#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
#define SIGPIPE 13 /* Broken pipe (POSIX). */
#define SIGALRM 14 /* Alarm clock (POSIX). */
#define SIGTERM 15 /* Termination (ANSI). */
#define SIGSTKFLT 16 /* Stack fault. */
#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
#define SIGCHLD 17 /* Child status has changed (POSIX). */
#define SIGCONT 18 /* Continue (POSIX). */
#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
#define SIGTSTP 20 /* Keyboard stop (POSIX). */
#define SIGTTIN 21 /* Background read from tty (POSIX). */
#define SIGTTOU 22 /* Background write to tty (POSIX). */
#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
#define SIGIO 29 /* I/O now possible (4.2 BSD). */
#define SIGPWR 30 /* Power failure restart (System V). */
#define SIGSYS 31 /* Bad system call. */


对于每种信号系统一般都有一个默认动作(一般是终止程序),然而除了SIGKILL,SIGSTOP 信号外,其他信号都可以被捕获并处理,
一个进程要向另外一个进程发生信号,可以通过kill -signal pid 或者调用函数kill发生


回到我们前面问题,为什么要nohup?因为我用使用Scrt这种终端工具退出的时候会向我们在当前shell下启动的进程发生一个SIGHUP信号,而SIGHUP信号的默认行为时终止进程,所以nohup的意思是屏蔽SIGHUP信号

下面我们做一个测试:

在一个窗口运行一个不带nohup的后台程序
[root@limt ~]# sh  Testlsof.sh > 111.log &
[1] 4486
[root@limt ~]# jobs
[1]+  Running                 sh Testlsof.sh > 111.log &
在另外一个窗口查看后台程序
[root@limt ~]# ps -ef|grep Testlsof
root      4486  4315  0 20:11 pts/1    00:00:00 sh Testlsof.sh
root      4574  4500  0 20:12 pts/0    00:00:00 grep Testlsof
关闭第一个窗口,后台进程也退出
[root@limt ~]# ps -ef|grep Testlsof
root      4661  4500  0 20:12 pts/0    00:00:00 grep Testlsof
 
在一个窗口运行一个带nohup的后台程序
[root@limt ~]# nohup sh Testlsof.sh > 111.log &
[1] 2710
[root@limt ~]# nohup: 忽略输入重定向错误到标准输出端
[root@limt ~]# jobs
[1]+  Running                 nohup sh Testlsof.sh > 111.log &
在另外一个窗口查看后台程序
[root@limt ~]# ps -ef|grep Testlsof
root      2710  2664  0 20:23 pts/1    00:00:00 sh Testlsof.sh   //父进程为shell
root      2794  2728  0 20:23 pts/2    00:00:00 grep Testlsof
关闭第一个窗口,后台进程没有退出
[root@limt ~]# ps -ef|grep Testlsof
root      2710     1  0 20:23 ?        00:00:00 sh Testlsof.sh   <span style="font-family: Arial, Helvetica, sans-serif;">//父进程为init进程</span>
root      3223  2728  0 20:23 pts/2    00:00:00 grep Testlsof

 

怎么证明关闭终端发生的是SIGHUP信号?可以使用trap命令屏蔽SIGHUP,SIGHUP的值为1,使用如下命令:

[root@limt~]# csh
[root@limt~]# sh  Testlsof.sh > 111.log &
[1]4602
[root@limt~]# jobs
[1]  + Running                       sh Testlsof.sh > 111.log
 
在另外一个窗口查看后台程序
[root@limt~]# ps -ef|grep Testlsof
root     4602 4509  0 20:31pts/1   00:00:00sh Testlsof.sh
root     4658 4524  0 20:32pts/0   00:00:00grep Testlsof
关闭第一个窗口,后台进程没有退出
[root@limt~]# ps -ef|grep Testlsof
root     4602    1  0 20:31?        00:00:00sh Testlsof.sh
root     4676 4524  0 20:32pts/0   00:00:00grep Testlsof

 

 

0 0
原创粉丝点击