스크립트가 있습니다
$ 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
신호 트랩을 사용하고 백그라운드에서 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