我有一个脚本
$ cat my.sh
#! /bin/bash -
dirs -l > /tmp/test/dirs_record
jobs > /tmp/test/jobs_record
因此,当我执行此操作时source ./my.sh
,它将在调用 shell 中输出目录堆栈和作业。
我还有另一个脚本schedule.sh
#! /bin/bash -
while : ; do eval "${@}" ; sleep 10 ; done
source schedule.sh source ./my.sh
在 bash shell 中运行可以定期地记录调用 bash shell 中的目录堆栈和作业。
但我想在同一个 shell 中运行其他命令,并且想source schedule.sh source ./my.sh
定期记录最新的目录堆栈和作业,所以我将其放在后台source schedule.sh source ./my.sh &
,然后因为jobs
和dirs
正在子 shell 中运行,而不是调用 shell,对调用 shell 的作业或目录堆栈的任何更改都不会被记录。看 为什么“jobs”和“dirs”在命令替换、进程替换、管道和后台作业中运行时输出与原始 shell 中的输出相同?
如何在不占用shell的情况下定期记录shell的dir stack和jobs?例如,我可以直接在调用 shell 中运行后台作业吗?
谢谢。
答案1
您可以使用信号陷阱并在后台运行 sleep && Kill 来完成此操作:
$ cat monitor.sh
# monitor stuff in the background
# ensure this file is sourced, not executed: http://mywiki.wooledge.org/BashFAQ/109
sourced() { [[ ${FUNCNAME[1]} == "source" ]]; }
sourced || { echo "source me"; exit 1; }
unset -f sourced
__MY_PID=$$
trap __usr1_trap USR1
__usr1_trap() {
dirs -l >| /tmp/test/dirs_record
jobs >| /tmp/test/jobs_record
__schedule_trap &
}
__schedule_trap() {
sleep 60
kill -USR1 $__MY_PID
}
# trigger the signal handler, which will reschedule itself
kill -USR1 $__MY_PID
启动它. /path/to/monitor.sh
请注意,我>|
在信号处理程序中使用重定向运算符,因为我运行以set -o noclobber
避免意外覆盖文件:这里我们想要故意覆盖文件。