linux中nohup 与 & 的区别
Posted kn-zheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux中nohup 与 & 的区别相关的知识,希望对你有一定的参考价值。
Linux/Unix下,通常只有守护进程可在脱离终端的情况下能继续执行,而普通进程在关闭终端时会因收到SIGHUP信号(挂起信号)而退出。当终端退出后,由该终端启动的后台程序自动退出。
若想命令在后台运行,则可用 & 指定命令在后台运行;
若想终端退出后程序不停止运行,则可用nohup命令启动后台程序。
nohup(=no hang up),使命令忽略SIGHUP信号;
[语法] nohup Command [ Arg ... ] [&]
[命令输出说明]
Command 的输出如果没有被重定向,则无论是标准输出(stdout),还是标准错误(stderr),均重定向到nohup.out文件;nohup.out文件缺省写在当前目录下,如果在该目录下无写权限,则试图写到$HOME/nohup.out中,如果仍然失败,整个命令执行失败;
Command的输出如果重定向,则写入指定的重定向文件中;
[退出状态]
126 能查找但不能调用 Command 命令;
127 nohup 命令发生错误或找不到 Command 命令;
否则为 Command 命令的退出状态;
nohup与&的区别:
nohup只是让命令忽略SIGHUP命令而已;
&则让命令在后台运行;
至于该命令是否能在脱离终端后继续执行则要看进程是否是守护进程,如果不是,则需要nohup来帮忙;
PS,引用 http://www.cnblogs.com/allenblogs/archive/2011/05/19/2051136.html
---------以下为引用内容
————————————————
nohup -- invoke a utility immune to hangups : 运行命令忽略挂起信号
& 是指后台运行;
nohup 的功能和& 之间的功能并不相同。其中,nohup 可以使得命令永远运行下去和用户终端没有关系。当我们断开ssh 连接的时候不会影响他的运行。而& 表示后台运行。当ssh 断开连接的时候(用户退出或挂起的时候),命令也自动退出。
当然我们可以把两者结合起来使用:
nohup command &
来实现命令的后台运行并且和用户终端没有关系。
由 nohup 文档来看:
If the output file nohup.out cannot be created in the current directory, the nohup utility uses the directory named by HOME to create the file.
表示:nohup 命令执行后,会产生日志文件,把命令的执行中的消息报损到这个文件之中。如果当前文件不可写,那么会自动保存到执行这个命令的home 目录下面。如果是超级管理员root 对应的是/root 目录。
从上面对比我们发现:
1. & 可以使得命令 免疫 ctrl c 的 SIGINT 信号,不能是的命令对 SIGHUP 信号进行免疫。
2. nohup 可以使得命令对两个信号都可以进行免疫。
为了使得 & 达到相同的效果:
我们可以使用如下操作:
如果已经使用 & 命令进行 后台运行。
可以使用disown -h 让任务忽略sighup 信号;
同样不会因为控制台的终端而中断任务。
展示:
断开终端重新登录时:
这样当你在大量备份文件的时候,如果出现断网或者不得不下线的时候。我们可以使用。
ctrl z 挂起任务;disown-h 使得任务 忽略sighup 信号;使用 bg 命令使得命令后台运行。这样就可以放心得下线了。
参考链接:
1. https://blog.csdn.net/zhang_Red/article/details/52789691
2. https://blog.csdn.net/stpeace/article/details/76389073
1.1 nohup
功能:不挂断运行命令
语法:nohup Command [ Arg … ] [ & ]
无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。
如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。
退出状态:该命令返回下列出口值:
126: 可以查找但不能调用 Command 参数指定的命令。
127: nohup 命令发生错误或不能查找由 Command 参数指定的命令。
否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态。
1.2 &
功能:命令在后台运行,功能与Ctrl+z
相同,一般配合nohup一起使用
eg:nohup ~/user/test.sh>output.log 2>&1 &
命令详解:
nohup ~/user/test.sh>output.log
不挂断运行test.sh
,输出结果重定向到当前目录的output.log
- 最后的
&
表示后台运行 2>&1
0
表示键盘输入,1
屏幕输出即标准输出,2
表示错误输出。其中2>&1
表示将错误信息重定向到标准输出 试想一下,如果2>&1
指将错误信息重定向到标准输出,那2>1
指什么? 分别尝试2>1
,2>&1
$ ls >outfile
$ cat outlog
outlog
test.sh
$ ls xxx>outfile
ls: cannot access xxx: No such file or directory
$ cat outfile
(这里是空)
$ ls xxx 2>1
$ cat 1(可以看出,将错误信息重定向到文件1里面了)
ls: cannot access xxx: No such file or directory
也就是说2>1
会将错误信息重定向到文件1里面,所以2>&1
中的&1
指标准输出
2. 查看后台运行的进程
2.1 jobs的使用
jobs命令用于显示Linux中的任务列表及任务状态,包括后台运行的任务。该命令可以显示任务号及其对应的进程号。其中,任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的。一个任务可以对应于一个或者多个进程号。
语法: jobs(选项)(参数)
选项
-l:显示进程号; -p:仅任务对应的显示进程号; -n:显示任务状态的变化; -r:仅输出运行状态(running)的任务; -s:仅输出停止状态(stoped)的任务。
常用命令: jobs -l
其中,输出信息的第一列表示任务编号,第二列表示任务所对应的进程号,第三列表示任务的运行状态,第四列表示启动任务的命令。
缺点:jobs命令只看当前终端生效的,关闭终端后,在另一个终端jobs已经无法看到后台跑得程序了,此时利用ps(进程查看命令)
2.2 ps的使用
ps命令用于报告当前系统的进程状态。可以搭配kill指令随时中断、删除不必要的程序。ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的。
常用命令:ps -aux
a:显示所有程序 u:以用户为主的格式来显示 x:显示所有程序,不以终端机来区分
通常与nohup &
配合使用,用于查看后台进程ID 配合 kill命令杀掉程序
常用命令:ps -aux|grep test.sh| grep -v grep
注:grep -v grep
用grep -v参数可以将grep命令排除掉
Linux nohup和&的功效
nohup和&究竟有啥区别?不少同学进行了回复,但并不是所有同学都理解得全对,今天把自己挖的坑自己填了。
测试代码如下:
是一个输出hello与循环轮数的死循环程序,每输出一行就休眠1秒。
使用 ./a.out 前台运行程序,会是什么效果呢?
程序每隔一秒会在终端输出一个字符串。
此时如果键入Ctrl+C ,程序会收到一个SIGINT信号,如果不做特殊处理,程序的默认行为是终止(如上图)。
使用 ./a.out& 后台运行程序,会是什么效果呢?
如上图:
-
首先会在终端显示进程号是32389
-
键入Ctrl + C,发出SIGINT信号,程序会继续运行
ps确认一下,确认进程依然在运行,进程号是32389。
此时如果关掉session,程序会收到一个SIGHUP信号,此时会怎么样呢?
ps再次确认,可以看到关闭session之后,进程号是32389的a.out进程也关闭了。
使用nohup ./a.out 又会是什么效果呢?
使用nohup 运行程序a.out,会发现:
-
前台没有出现进程号
-
有一个“忽略输入,输出至nohup.out”的提示
-
hello的输出也没有出现在前台
手动ps看进程号,这次a.out的进程号是32437。
此时如果关掉session,程序会收到一个SIGHUP信号,程序会不会关闭呢?
关掉session后,再次ps看一下,ID为32437的a.out进程还在。
这些只能通过kill把程序干掉了,killall之后,ps查看进程已经关闭。
killall之后,查看发现多了一个nohup.out文件,不过这个文件的大小是0,有点奇怪,启动程序的时候,明明提示了“appending output to nohup.out”呀,先把问题遗留在这,测试一下Ctrl +C。
仍如上图,使用nohup启动a.out,如果键入Ctrl+C ,程序收到SIGINT信号后,直接关闭了。
最后测试一下nohup和&同时使用,即用nohup./a.out &运行程序,又会是什么效果呢?
使用nohup ./a.out &运行程序后,可以看到:
-
会在终端显示进程号是32524
-
也会有一个“忽略输入,输出至nohup.out”的提示
键入Ctrl + C,发送SIGINT信号,似乎没反应。
关闭session,发送SIGHUP信号,再来看看。
ID为32524的进程依然存在,后续也只能用kill来关闭它。
结论
使用&后台运行程序:
-
结果会输出到终端
-
使用Ctrl + C发送SIGINT信号,程序免疫
-
关闭session发送SIGHUP信号,程序关闭
使用nohup运行程序:
-
结果默认会输出到nohup.out
-
使用Ctrl + C发送SIGINT信号,程序关闭
-
关闭session发送SIGHUP信号,程序免疫
平日线上经常使用nohup和&配合来启动程序:
-
同时免疫SIGINT和SIGHUP信号
同时,还有一个最佳实践:
-
不要将信息输出到终端标准输出,标准错误输出,而要用日志组件将信息记录到日志里
本文转载自微信公众号:架构师之路,因为老找不到地址,做下记录~
以上是关于linux中nohup 与 & 的区别的主要内容,如果未能解决你的问题,请参考以下文章