可以通过 cron 安排命令定期运行。
我想知道如何在给定的交互式 bash shell 中定期在后台运行命令?
我想从给定的交互式 bash shell(而不是正在运行的其他 shell)运行该命令,因为我需要该命令根据 shell 的状态生成输出,例如
jobs
给定 shell 中的输出。我想在后台运行该命令,因为我希望能够继续在同一 shell 中运行其他命令
该命令可能是一个脚本,为了让脚本访问给定 shell 的状态,我可能需要
source
shell 中的脚本。
例如:
我写了一个这样的脚本的例子:
$ 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 &
但获取脚本最新输出的文件不包含jobs
或dirs -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
有两个问题:
- 该脚本在非交互式子 shell 中运行(与父 shell 不同)。
- 子 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,该文件将为空。