如何在不占用shell的情况下定期记录shell的dir stack和jobs?

如何在不占用shell的情况下定期记录shell的dir stack和jobs?

我有一个脚本

$ 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 &,然后因为jobsdirs正在子 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避免意外覆盖文件:这里我们想要故意覆盖文件。

相关内容