【问题标题】:bash nohup with two commands带有两个命令的 bash nohup
【发布时间】:2014-02-10 15:02:04
【问题描述】:

我的bashrc 中有一个小函数,因此我可以运行脚本并在完成后将输出发送到我的电子邮件。代码如下:

run() {
    email=example@gmail.com
    last="${!#}"
    rest="${@:1:($#-1)}"

    (nohup $rest &> $last < /dev/null; mail -s "$rest" "$email" < "$last") &
}

函数是这样使用的

run ./script.sh arg1 arg2 output

它似乎大部分时间都在工作,但有时即使脚本完成,电子邮件也不会发送。我怀疑这与我关闭服务器终端有关。在这些情况下,由于nohup,脚本仍在运行,但它不会在最后发送电子邮件。为了让它正常工作,我真的很感激一些指示。

【问题讨论】:

  • rest="${@:1:($#-1)}" 是个坏主意——你不能用标量准确地表示一个参数向量,所以这会冒着参数被不正确地分割字符串、全局扩展等的风险。你不过,可以使用rest=( "${@:1:($#-1)}" ),然后使用"${rest[@]}" 扩展它(或者,对于单参数主题行版本,"${rest[*]}"...,或者更准确地说,printf -v rest_cmd '%q ' "${rest[@]}",然后使用"$rest_cmd" 作为邮件参数)
  • 谢谢你的提示,我一定会改变的。

标签: bash sh nohup


【解决方案1】:

有多种方法可以解决这个问题,但我想我会推荐这个:

run() {
  email=example@gmail.com
  rest="${@:1:($#-1)}"

  nohup bash -c "$rest < /dev/null 2>&1 | mail -s \"$rest\" \"$email\"" &
}

问题是您的nohup 命令以/dev/null 之后的分号结束,因此不适用于mail 部分。 ( ... ) 引入了一个子shell,但不是外部命令,因此nohup ( ... ) 不起作用,这就是为什么需要bash -c "..."(如果这很重要,您也可以使用${SHELL} -c " ..." 来增加可移植性)。当包含在另一组引号中时,您需要转义双引号。此外,临时文件不是必需的(除非您出于某种原因想要保留它 - 如果是这种情况,请随时将重定向放回并用;而不是|分隔命令)。在不需要输出文件的情况下,您也可以省去 rest=... 位并将其称为 run script.sh arg1 arg2,但如果您已经在其他代码中调用了它,则保留该位可能更简单 - 你必须弄清楚那部分......

【讨论】:

  • 谢谢!我实际上尝试了nohup (...),我真的很困惑它不起作用!
  • 输出文件对我很有用,所以我将您的脚本更改为 nohup bash -c "$rest &amp;&gt; $last ; mail -s \"$rest\" \"$email\" &lt; \"$last\"" &amp;&gt; /dev/null &lt; /dev/null &amp; &lt; /dev/null 的目的是避免 nohup 警告消息 nohup: ignoring input。出于同样的目的,我在末尾添加了&amp;&gt; /dev/null
  • 很好地解释了为什么 subshel​​l 选项不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多