我们如何安排在给定的交互式 bash shell 中定期在后台运行命令?

我们如何安排在给定的交互式 bash shell 中定期在后台运行命令?

可以通过 cron 安排命令定期运行。

我想知道如何在给定的交互式 bash shell 中定期在后台运行命令?

  • 我想从给定的交互式 bash shell(而不是正在运行的其他 shell)运行该命令,因为我需要该命令根据 shell 的状态生成输出,例如jobs给定 shell 中的输出。

  • 我想在后台运行该命令,因为我希望能够继续在同一 shell 中运行其他命令

  • 该命令可能是一个脚本,为了让脚本访问给定 shell 的状态,我可能需要sourceshell 中的脚本。

例如:

我写了一个这样的脚本的例子:

$ pwd
/tmp/test
$ cat test.sh 
#! /bin/bash

while true;
do
    dirs -l -p  > /tmp/test/dirs
    jobs > /tmp/test/jobs
    sleep 5
done

然后在交互式 bash shell 中运行它:

$ source test.sh &

但获取脚本最新输出的文件不包含jobsdirs -l -p直接在给定 shell 中运行的输出:

$ evince &
$ jobs
[1]-  Running                 source test.sh &
[2]+  Running                 evince &
$ cat /tmp/test/jobs 
$

$ pushd /tmp/
/tmp /tmp/test    
$ dirs -l -p
/tmp/test
/tmp    
$ cat /tmp/test/dirs 
/tmp/test

我想知道为什么?我们怎样才能完成文章开头的任务呢?

谢谢。

答案1

有两个问题:

  1. 该脚本在非交互式子 shell 中运行(与父 shell 不同)。
  2. 子 shell 没有作业控制。

简单地通过启动脚本来在子 shell 中启用作业控制bash -m test.sh &是行不通的,因为这也意味着它将继承父 shell 中的所有文件描述符。当您按下时,首先发生的事情Enter是脚本将被暂停。

相反,让我们将“定期”解释为“每次我按下Enter执行新命令时”。

这意味着我们可以将脚本的主要部分放入PROMPT_COMMAND其中。如果此变量有值,则在发出下一个提示之前对其进行评估。

PROMPT_COMMAND='jobs >/tmp/test/jobs'

如果我们sleep 100 &在提示符后运行并调查/tmp/test/jobs,我们将看到它包含

[1]+  Running                 sleep 100 &

100 秒后,如果没有进一步启动后台作业,则按Enter将更新文件以包含

[1]+  Running                 sleep 100 &
[1]+  Done                    sleep 100

接下来Enter,该文件将为空。

相关内容