我正在尝试运行一个后台作业,该作业应在终止后发送电子邮件。后台作业可以运行几个小时,并且应该独立于启动它的 Shell 运行(因为 SSH 将断开连接)。在下面的当前脚本中,邮件命令不会等待 BACKGROUNDJOB 终止。我该如何实现这一点?
nohup BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr &
mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr [email protected] <<< "job finished on $HOSTENAME on $(date)"
邮件应附加来自 BACKGROUNDJOB 的 2 个输出文件,这些文件只有在 BACKGROUNDJOB 终止后才可用。
Or generally:
#Script.sh
Process 1 (e.g. run rsync) [this could take 10h and only then rsync.log is available]
Process 2 (send email with rsync.log as attachment)
#end script
并且整个脚本应该放在后台独立运行,即使 ssh 断开连接也能继续运行。
答案1
...并且应该独立于启动它的 Shell 运行
它不能独立于启动它的 Shell 运行...它需要 Shell 一直解释其命令直到结束/退出。
(因为 SSH 会断开连接)
断开 SSH 将导致断开用户终端的连接,从而导致SIGHUP
(挂断)信号,后者将导致 shell 终止,因为 shell 仅仅是父用户终端的一个子进程... 在 中,你可以告诉你的 shell使用内置的作业控制bash
来忽略信号SIGHUB
disown
在我当前的脚本中,邮件命令不会等待 BACKGROUNDJOB 终止。我该如何实现这一点?
如果您按顺序嵌套命令,例如comman1; command2; ...
不将任何先前的命令发送到后台,例如:
BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr; mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr [email protected] <<< "job finished on $HOSTENAME on $(date)"
那么后一个命令就会等待前一个命令先执行完成。
整个脚本应该放在后台运行,独立于“shell”运行(你的意思是家长终端)即使 ssh 断开连接也能继续运行。
你可以像这样实现它(这里可能并不总是需要子 shell 语法(...)
,但在所有情况下使用也不会有什么坏处):
(/path/to/scriptfile) & disown
或者,如果您喜欢按顺序嵌套命令,如下所示((...)
这里需要子 shell 语法):
(BACKGROUNDJOB -l $corefolder/$filename >/dev/nul 2> $corefolder/$filenameerr; mail -s "JOB DONE" -A $corefolder/$filename -A $corefolder/$filenameerr [email protected] <<< "job finished on $HOSTENAME on $(date)") & disown