2

你好。我是 shell 新手,正在编写我的第一个组合脚本。我已经阅读了整个 intertube 和 SO,并且有很多很多地方disown解释了nohup,&return,但有些东西对我不起作用。

我想要一个更简单的计时器。该脚本要求用户输入小时、分钟等,然后:

echo "No problem, see you then…"
sleep $[a*3600+b*60+c]

此时(在第一行或第二行,不确定)我希望脚本或脚本中的特定命令成为后台进程。也许是一个守护进程?这样计时器仍然会按计划进行,即使

  • 该终端窗口已关闭
  • 终端应用程序完全退出
  • 计算机进入睡眠状态(我意识到我可能还需要一些不同的代码来唤醒 Mac 本身)
  • 同样在“没问题”行之后,我想要一个return命令,以便现有的 shell 窗口在此期间仍然有用。

    终端通知器命令(定时器唤醒)在上述某些用法下立即被调用(我现在不记得是哪个),然后在正确的时间发出第二个通知。在任何地方使用该return命令基本上似乎退出了脚本。

    我不清楚的一件事是 , 等是否/如何disown适用nohup于命令进程与脚本进程,即它们中的任何一个是否只能在脚本中的命令上正常工作(如果不是,如何将脚本初始化为仍然要求输入的后台进程)。

    也许我应该使用一些替代方法sleep

    4

    2 回答 2

    5

    无需使用单独的脚本或让脚本自行运行以使其一部分在后台运行。

    一个更简单的方法是将您想要作为背景的部分(睡眠和后续命令)放在括号内,并在它们后面加上一个&符号。

    所以脚本的结尾看起来像:

    (
      sleep $time
      # Do whatever
    )&
    

    这将导致该部分代码在放置在后台的子shell中运行,因为在此之后没有代码,第一个shell将立即退出,将控制权返回给您的交互式shell。

    于 2012-10-24T23:07:27.063 回答
    0

    当您的脚本运行时,它实际上是通过启动一个新的 shell 来执行它来运行的。为了让您的脚本进入后台,您需要将该 shell 发送到后台,您不能这样做,因为您需要与其父 shell 进行通信。

    您可以做的是让您的脚本使用特殊参数调用自身,以指示它应该完成工作:

    #! /bin/zsh
    if [ "$1" != '--run' ] ; then
        echo sending to background
        $0 --run $@ &
        exit
    fi
    sleep 1
    echo backgrounded $@
    

    该脚本首先检查其第一个参数是否为--run. 如果不是,那么它$0使用该参数和它$@在后台接收的所有其他参数 () 调用自身 (),然后退出。您可以使用类似的方法,在您想进入后台时执行测试,并可能发送您需要的数据而不是每个参数。例如,仅发送秒数:

    $0 --run $[a*3600+b*60+c] &
    
    于 2012-10-22T20:14:19.833 回答