백그라운드에서 함수를 호출하는 bash 스크립트가 있습니다.
process_manager $1 $2 $3 &
이 함수는 인수로 전달된 명령을 백그라운드에서 실행/실행합니다.
process_manager 함수에서 하위 프로세스 목록을 얻는 방법은 무엇입니까?
나는 이것을 시도한다:
process_manager () {
count=$1
interval=$2
cmd=$3
bash_pid=$$
last_pid=$!
echo "bash_pid: $bash_pid, ppid: $PPID, last_pid: $last_pid"
$cmd &
$cmd &
sleep 30 &
}
process_manager $1 $2 $3 &
process_manager $1 $2 $3 &
process_manager $1 $2 $3 &
그러나 이 함수 process_manager는 첫 번째 호출에서 $! 또는 $last_pid를 표시하지 않습니다.
이 경우 $last_pid를 어떻게 얻고 하위 프로세스 목록에 액세스할 수 있습니까?
답변1
$$
쉘의 pid를 포함합니다.처형된설명하기스크립트. 이 쉘의 모든 하위 쉘에서 동일합니다.
$!
백그라운드에서 실행되는 마지막 하위 명령의 pid를 포함합니다( &
coproc 또는 프로세스 대체 사용).
백그라운드에서 실행되는 명령에서는 $!
설정되지 않습니다. $!
자식 프로세스를 기다리거나 죽일 수 있는 부모 프로세스용입니다.
bash
$BASHPID
pid를 포함하는 변수 가 있습니다 .현재 서브쉘.
그것이 어떤 과정인지 항상 명확하지는 않습니다.
존재하다:
echo "$BASHPID"
이는 명령을 해석한 프로세스의 pid echo
이지만
/bin/echo "$BASHPID"
프로세스를 분기하지만 $BASHPID
분기된 프로세스의 pid를 보고하는 대신 상위 프로세스의 pid를 보고합니다. 그리고:
/bin/echo "$BASHPID" &
(유일한 차이점은 상위 프로세스가 하위 프로세스를 기다리지 않는다는 것입니다.) $BASHPID
분기된 프로세스의 pid를 보고합니다.
$ bash -c 'echo "$$"; echo "$BASHPID"; /bin/echo "$BASHPID"; /bin/echo $BASHPID &'
3264
3264
3264
3266
그러나 귀하의 경우에는 다음을 안전하게 수행할 수 있습니다.
process_manager () {
pid_of_last_command_run_in_background=$!
mypid=$BASHPID
cmd &
cmd1pid=$!
cmd &
cmd2pid=$!
}
$pid_of_last_command_run_in_background
백그라운드에서 실행되는 마지막 명령의 pid입니다(현재 하위 쉘이나 해당 상위 쉘 또는 해당 조상에 의해). 그렇기 때문에 $last_pid
두 번째 실행에서는 무언가(이전 process_manager의 pid)를 얻지만 첫 번째 실행에서는 얻지 못합니다.