Linux 执行一段 shell 命令加与不加 nohup 到底有什么区别?

2021-09-17 23:10:08 +08:00
 BaseException

请教 Linux 大佬、运维大佬,标题中的问题。下面我先抛砖引玉。

nohup 英文全称 no hang up (不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。 nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。

以上来自 https://www.runoob.com/linux/linux-comm-nohup.html

执行一个 java 程序,使用命令 1 或 2

  1. java -jar xxx.jar >> ./xxx.log 2>&1 &
  2. nohup java -jar xxx.jar >> ./xxx.log 2>&1 &

问题 1:

我使用命令 1 执行的程序,在退出终端之后,进程依然很好的存活着啊,nohup 的真正作用是什么?

问题 2:

>> ./xxx.log 这个 >> 跟文件之间需要空格吗?还是有没有空格都一样,我经过测试似乎是一样达到目的的。我知道 > 是直接覆盖, >> 是追加到文件(如果之前文件存在且有内容)。

谢谢彦祖们。

4565 次点击
所在节点    Linux
25 条回复
jaredyam
2021-09-17 23:18:54 +08:00
你的问题一的前提,可能只在你的终端 GUI 下成立,比如 XShell 。
momocraft
2021-09-17 23:21:07 +08:00
1 重写信号 handler 使进程收到 HUP 信号时不退出

比如 busybox 版的 nohup https://elixir.bootlin.com/busybox/latest/source/coreutils/nohup.c
前面都是重定向到文件, "真正作用" 就是 94 行的 signal 和 exec.

2 一样. >>和文件名是两个 token , 中间随便多少个空格都一样
BaseException
2021-09-17 23:21:23 +08:00
@jaredyam #1 windows terminal 上运行着的 git bash
westoy
2021-09-17 23:23:56 +08:00
退出终端后, 你之前那个终端派生的进程都变成了孤儿进程, 会响应系统的 SIGHUP 信号把进程挂掉, nohup 干的就是无视这个信号和重定向输出

你跑的那个 java 如果自己实现了 daemon 就不受影响了啊
BaseException
2021-09-17 23:25:09 +08:00
@momocraft #2 感谢。但我还是没怎么懂问题 1,有最佳实践吗,更加推荐 nohup java -jar xxx.jar >> ./xxx.log 2>&1 & 这种写法么
BaseException
2021-09-17 23:26:49 +08:00
@westoy #4 谢谢,醍醐灌顶。我跑的 java 程序引入了 quartz,然后有根据 cron 表达式一直运行着
ysc3839
2021-09-17 23:30:38 +08:00
1. 可能这个程序自己已经忽略 SIGHUP 了。
2. 印象中不用。
momocraft
2021-09-18 01:04:58 +08:00
重要程序建议用更稳定的方式跑, 比如用 daemon 管理. nohup 连自动重启都没有.

不重要的随便
ch2
2021-09-18 01:33:22 +08:00
daemon 进程不需要加 nohup,nohup 是让非 daemon 进程脱离 tty 的一种方法
msg7086
2021-09-18 03:06:23 +08:00
单次运行用 nohup,长期反复运行用系统服务。
mrqyoung
2021-09-18 09:03:18 +08:00
顺便,2>&1 这种可以简写为 &>1 。例如:`java -jar xxx.jar &> xxx.log &` 以及 `java -jar xxx.jar &>> xxx.log & `
lululau
2021-09-18 09:36:14 +08:00
4 楼正解
salmon5
2021-09-18 09:55:50 +08:00
建议使用 java -jar xxx.jar >> ./xxx.log 2>&1 &
nohup 不建议用,就当它不存在吧,这个命令有点多余
salmon5
2021-09-18 09:56:41 +08:00
生产中,一般用 supervisor 或者容器
rrfeng
2021-09-18 10:03:41 +08:00
shopt 了解一下
BaseException
2021-09-18 10:29:34 +08:00
@ysc3839 #7 dei
@momocraft #8 嗯嗯 是的 可以考虑 systemd 或者 supervisor 或者 build docker image 然后用容器跑
@salmon5 #13 🤣
@salmon5 #14 嗯嗯
@rrfeng #15 好的 谢谢我了解一下
nbweb
2021-09-18 10:41:01 +08:00
@salmon5 现在不都改成 systemctl 了呢,supervisor 在 systemctl 出来之前一直在用,实在奇怪,干嘛不把 supervisor 弄成默认的管理进程,论资历和历史,supervisor 都很老啊。
salmon5
2021-09-18 14:16:58 +08:00
@nbweb systemd 偏向于系统组件的,supervisor 偏向于业务,比如一堆 java 程序,如果和 systemd 耦合在一起很不优雅;
salmon5
2021-09-18 14:18:50 +08:00
systemd 比 supervisor 庞大的多,supervisor 比较轻量
mutalisk
2021-09-18 14:22:23 +08:00
ignore SIGHUP singal

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/802649

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX