スクリプトがあります
$ cat my.sh
#! /bin/bash -
dirs -l > /tmp/test/dirs_record
jobs > /tmp/test/jobs_record
したがって、これを行うと、source ./my.sh
呼び出しシェルにディレクトリスタックとタスクが出力されます。
他のスクリプトがありますschedule.sh
#! /bin/bash -
while : ; do eval "${@}" ; sleep 10 ; done
source schedule.sh source ./my.sh
Bashシェルで実行すると動作します。定期的に呼び出し bash シェルにディレクトリスタックとタスクを記録します。
ところで、同じシェルで別のコマンドを実行したいのですが、最新のディレクトリスタックとジョブを定期source schedule.sh source ./my.sh
的に記録したいので、バックグラウンドに置いてから、 をシェルを呼び出す代わりにサブシェルで実行しているsource schedule.sh source ./my.sh &
ため、呼び出す作業を行います。シェルまたはディレクトリスタックへの変更は記録されません。バラより jobs
dirs
コマンド置換、プロセス置換、パイプ、バックグラウンドジョブで実行すると、「jobs」と「dirs」が元のシェルと同じように出力されるのはなぜですか?
シェルを占有せずにシェルのディレクトリスタックとタスクを定期的に記録する方法は?たとえば、呼び出しシェルから直接バックグラウンドタスクを実行できますか?
ありがとうございます。
ベストアンサー1
シグナルトラップを使用してバックグラウンドでスリープ&&キルを実行することでこれを行うことができます。
$ 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