初始接触nohup指令
在部署代码时,对于war包我们直接把它丢进tomcat下的webapps目录下,war包会自动解压,程序会自动启动。那么对于jar程序呢?假设我们的jar程序的名称叫做Demo.jar
。
我们通过执行java -jar Demo.jar
来启动程序,可是我们却不能执行其他操作,而当我们按Ctrl+C
或者直接退出登录,程序就终止了。这样并不满足生产环境的需求。
于是我们网上一搜,照瓢画葫芦,可以写出这样的命令:nohup java -jar Demo.jar 2>&1 &
然后发现能后台运行了,退出登录再登录,发现程序也还是在的。这是第一次接触nohup
指令。
后来使用过ffmpeg进行推流,一样的,终端总有关闭的时候,可是我的服务还是得继续运行啊。于是网上一搜,又是要用到nohup
指令。
疑惑与了解
于是我就以为nohup
这个全称为no hand up的命令,可以实现后台运行jar程序。想当然的以为2>&1 &
是用来修饰nohup
的,其实大错特错。
但其实不是,nohup全称是no hand up,表示不挂断的意思。当我们执行的是nohup java -jar Demo.jar
的时候,我们直接退出登录,程序确实还在跑。可如果我们不是退出登录,而是想要继续做其他操作,会发现我们是无法进行其他操作的,除非先通过Ctrl+C
终止当前的程序。
也就是说,nohup
并没有后台运行的作用,该命令的作用,是可以在你退出帐户/关闭终端之后继续运行相应的进程。
那为什么我们的执行nohup java -jar Demo.jar 2>&1 &
程序就可以后台运行呢,很显然,起到后台运行功能的关键在后面。事实上,起到后台运行的是该命令的最后一个符号:&
。通过加上&
,可以使得程序可以在后台运行。
所以你的意思是如果我执行的是java -jar Demo.jar &
的话,当运行程序后,我通过Ctrl+C终止当前的标准输出,程序还是能运行的??是的,理论上是这样的。可我还真的没试过呢。
而在操作之后,我发现,确实如此。那么既然java -jar Demo.jar &
可以使得程序在后台运行,为什么我们还要在前面加上nohup
呢?
因为只是单纯使用java -jar Demo.jar &
的话,程序确实是可以后台运行,可是当我们退出账户/关闭终端后,程序也会结束。
因此我们通过nohup
+&
,可以实现程序后台运行并且程序不被挂起的效果。
解析nohup java -jar Demo.jar 2>&1 &命令
说实话,类似这样的指令执行过挺多次了,可还是没办法记住,而且还经常混淆如为什么是2>&1
而不是2>1
,为什么是2>log
而不是2>&log
,为什么2>&1 &
会出现两个&
…
其实说到底,就是没把指令给理解透,才会出现混线的情况。今天又接触了一次,于是就想顺便给消化掉。
对于指令nohup java -jar Demo.jar 2>&1 &
,我们可以拆分为4部分:
1、nohup
:不挂起执行;
2、java -jar Demo.jar
:启动程序;
3、2>&1
:输出重定向;
4、&
:后台执行;
可以说1、3、4都是用于辅助2的。即第2部分启动程序才是核心。
前面介绍了,nohup
可以让程序不被挂起,即时关闭终端或者退出登录程序也能运行,&
可以让程序在后台保持运行,而第三点用于输出重定向输出。
如果单独执行java -jar Demo.jar
,那么输出的日志就会默认直接输出到终端,而如果加上nohup
,即nohup java -jar Demo.jar
,那么输出的日志就会默认输出的nohup.out
文件中。
下面着重来讲第三点——输出重定向。
在shell中,0
表示标准输入,1
表示标准输出,2
表示标准错误。
而>
表示重定向,而2>&1
中的&
则表示等同于的意思。
因此下面的操作就很好理解了:
> file
表示将标准输出输出到file中,即相当于1>file
,2>error
表示将标准错误输出到error中,2>&1
表示将标准错误也输出到标准输出中,>/dev/null 2>&1
表示将标准错误重定向到标准输出中,并将标准输出输出到无底洞中(即不记录)
之所以要重定向,是因为有的时候我们需要记录全部日志,而有的时候我们只需要记录错误信息,或者有的时候我们程序内部已经记录了日志因此不需要额外再记录日志。
因此就需要输出重定向。
扩展
输出重定向和&
也可以和其他指令配合使用。如我们使用指令统计接口访问QPS,这个过程可能需要一点时间,于是我们可以使用&
让程序在后台执行,再通过输出重定向,把查询出来的QPS结果重定向到一个文本文件中。
这样我们在终端界面就可以马上进行其他操作无需等待了。
最后
我想,下次再次需要启动jar程序,应该可以完整的把指令写出来了。因为理解其中的含义,就不会混乱了。果然理解很重要。
参考文章
Linux nohup、&、2>&1是什么: