Linux nohup
约 1087 字大约 4 分钟
2025-01-11
介绍
nohup
英文全称 no hang up
(不挂起,不挂断),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
nohup
命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out
的文件到当前目录下,如果当前目录的 nohup.out
文件不可写,输出重定向到 $HOME/nohup.out
文件中。
提示 命令行默认启动的一些服务在退出终端后就会停止,使用nohup
命令在执行时,会自动忽略SIGHUP
信号,所以当终端关闭时,nohup
命令仍会继续执行,常用nohup
来启动一些服务。
语法
$ nohup Command [Arg] [&]
参数:
Command
:要执行的命令。Arg
:一些参数,可以指定输出文件。&
:让命令在后台执行,终端退出后命令仍旧执行。
使用
默认输出文件
在执行命令nohup sh xxx.sh &
的时候,提示:
nohup: ignoring input and appending output to `nohup.out’
意思是 :忽略输入并将输出附加到nohup.out
文件中。这个只是没有指定输出文件,默认输出到nohup.out
文件中的一个提示。如果不想要这个提示可以指定一个输出文件。
注意 如果不想输出内容,可以设置输出文件为/dev/null
,/dev/null
是一个特殊的文件,写入到它的内容都会被丢弃。
重定向输出
$ nohup python3 ./main.py >output.out 2>&1 &
Linux
中的0
表示标准输入,1
表示标准输出,2
表示标准错误输出。
output.out
是输出的文件,默认是nohup.out
2>&1
,2
是标准错误输出,1
是标准输出,这里的&
表示引用的意思,对标准输出的引用。>
左右不能有空格,即将错误内容重定向输入到标准输出中去。&
表示为后台运行
$ nohup python3 test.py >>output.out 2>&1 &
这里>>
的意思是追加,意思是将标准输出和标准错误输出都追加到output.out
文件中。 上面的>
的意思是覆盖追加,意思是将标准输出和标准错误输出都覆盖写到output.out
文件中。
注意如果不指定日志文件则会创建默认文件nohup.out
命令会输出创建进程的PID
。
$ nohup python3 ./wl_apscheduler.py &
[1] 82531
appending output to nohup.out
注意 当你成功地提交进程以后,就会显示出一个进程号,可以用它来监控或杀死该进程。(查看:ps -ef | grep 进程号
、杀死kill -9 进程号
)
查看nohup.out
查看nohup.out
可以了解进程在执行过程中的输出情况。如果进程执行成功,则nohup.out
文件中会显示nohup
命令的输出内容。如果进程执行失败,则nohup.out
文件中会显示进程执行失败的原因。
$ tail -f nohup.out
不使用nohup
和使用nohup
的对比
- 使用
sh nohup.sh
执行,当前命令行就会hang
住。 - 使用
sh nohup.sh &
执行,就会把作业提交到后台,释放当前命令行,同时显示了进程号。但是如果帮当前命令窗口关闭,整个作业就停止了。 - 使用
nohup sh nohup.sh >log 2>&1 &
,同样把作业提交到后台,释放当前窗口,而且即使把当前命令窗口关闭,作业仍然运行。
提示 可以使用ps -fe | grep 82531
也可以使用文件名称过滤ps -ef | grep nohup.sh
来查看后台作业运行情况。
$ ps -fe | grep 82531
501 82531 38435 0 10:27AM ttys009 0:00.16 python3 ./wl_apscheduler.py
501 82702 38435 0 10:29AM ttys009 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox 82531
nohup
命令在shell
脚本无法执行问题
我们希望在脚本中使用nohup
来启动一个进程,但是发现nohup
命令无法执行,提示找不到环境变量。
!#/bin/bash
nohup echo "hello world"
在脚本中加上 source /etc/profile
就好了
!#/bin/bash
source /etc/profile
nohup echo "hello world"
这是因为找不到环境变量,所以先source
一下就行了。
注意 在ssh
远程的时候执行nohup
命令,也是无法获取被远程机器的环境变量的。也需要添加source /etc/profile