0

I have a script

$ cat my.sh 
#! /bin/bash -
dirs -l > /tmp/test/dirs_record
jobs > /tmp/test/jobs_record

So when I source ./my.sh, it will output the dir stack and jobs in the invoking shell.

I have another script schedule.sh

#! /bin/bash -
while : ; do eval "${@}" ; sleep 10 ; done

Running source schedule.sh source ./my.sh in a bash shell can periodically record the dir stack and jobs in the invoking bash shell.

But I want to run other commands in the same shell, and want source schedule.sh source ./my.sh to record the up-to-date dir stack and jobs periodically, so I put it in background source schedule.sh source ./my.sh &, and then since jobs and dirs are running in a subshell instead of the invoking shell, any change to the jobs or dir stack to the invoking shell will not be recorded. See Why do `jobs` and `dirs` run in command subsitution, process substitution, pipeline, and background jobs output the same as in original shell?

How can I periodically record the dir stack and jobs of a shell without occupying the shell? For example, can I run a background job directly in the invoking shell?

Thanks.

1 Answer 1

1

You can do this with a signal trap, and running sleep && kill in the background:

$ 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

Launch it with . /path/to/monitor.sh

Note that I use >| as the redirection operator in the signal handler because I run with set -o noclobber to avoid accidentally overwriting files: here we want to overwrite the files on purpose.

5
  • Thanks. Is prefix __ naming convention to distinguish names created by you from those implicitly by the shell?
    – Tim
    Aug 2, 2018 at 22:56
  • Yeah. I picked it up from some coding convention that "private methods" start with an underscore. I'd be unlikely to type it by accident. Aug 2, 2018 at 23:11
  • How would you stop it from running? trap "" USR1?
    – Tim
    Aug 2, 2018 at 23:24
  • One strange problem when I run your script is that the signal stops being sent and trapped whenever the shell is idle i.e. without my running any command, Is it because __schedule_trap & need me to type RETURN key to finish sending the signal?
    – Tim
    Aug 2, 2018 at 23:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .