bash 带有 nohup 的脚本不能正确退出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29709790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:49:34  来源:igfitidea点击:

Scripts with nohup inside don't exit correctly

bashshellnohup

提问by user1595858

We have script which do some processing and triggers a job in background using nohup. When we schedule this script from Oracle OEM (or it can be any scheduler job), i see the following error and show status as failed but the script actually finished without issue. How to exit the script correctly when backup ground job is started with nohup?

我们有使用 nohup 进行一些处理并在后台触发作业的脚本。当我们从 Oracle OEM 调度此脚本(或者它可以是任何调度程序作业)时,我看到以下错误并将状态显示为失败,但脚本实际上没有问题地完成。使用 nohup 启动备份地面作业时如何正确退出脚本?

Remote operation finished but process did not close its stdout/stderr

file: test.sh

文件:test.sh

#!/bin/bash
# do some processing
...
nohup ./start.sh 2000 &

# end of the script

回答by dg99

By executing start.shin this manner you are allowing it to claim partial ownership of test.sh's output file descriptors (stdout/stderr). So whereas when mostbash scripts exit, their file descriptors are closed for them (by the operating system), test.sh's file descriptors cannot be closed because start.shstill has a claim to them.

通过start.sh以这种方式执行,您允许它声明test.sh的输出文件描述符 ( stdout/ stderr) 的部分所有权。因此,当大多数bash 脚本退出时,它们的文件描述符已为它们关闭(由操作系统),test.sh的文件描述符无法关闭,因为它们start.sh仍然拥有所有权。

The solution is to not let start.shclaim the same output file descriptors as test.shis using. If you don't care about its output, you can launch it like this:

解决方案是不要start.sh声明与使用相同的输出文件描述符test.sh。如果你不关心它的输出,你可以像这样启动它:

nohup ./start.sh 2000 1>/dev/null 2>/dev/null &

which tells the new process to send both its stdout and stderr to /dev/null. If you do care about its output, then just capture it somewhere more meaningful:

它告诉新进程将其 stdout 和 stderr 都发送到/dev/null. 如果您确实关心它的输出,那么只需将其捕获到更有意义的地方即可:

nohup ./start.sh 2000 1>/path/to/stdout.txt 2>/path/to/stderr.txt &