백그라운드 파이프라인 명령 시퀀스에서 모든 명령의 PID를 가져옵니다.

백그라운드 파이프라인 명령 시퀀스에서 모든 명령의 PID를 가져옵니다.

에 있는 경우 bash다음을 실행합니다.

cmd1 | cmd2 | ... | cmdi | ... | cmdn &

명확하지 않을 수도 있습니다 cmd{1..n}. PID를 어떻게 얻나요 cmdi? 아니면 어떻게 cmdi프로세스에 신호를 보낼 수 있나요? (예: 보내기 SIGUSR1?) pkill/ pgrepetc는 동일한 파이프라인의 일부를 포함하여 다른 인스턴스가 실행 중일 수 있으므로 pidof좋은 대답이 아닌 것 같습니다 . 의 PID를 알려 cmdi주세요 .jobs -pcmd1

i에서는 무엇이든 될 수 있습니다 {1..n}.

답변1

질문의 원래 버전에서는 마지막 명령의 PID만 필요할 때 특수 변수가 $!완벽합니다 .

foo | bar | baz &
baz_pid=$!

다른 프로세스의 PID에 쉽게 액세스할 수 있는 유사한 방법은 없습니다.

$pipestatus(zsh) 및 (bash) 를 추가하는 데 오랜 시간이 걸렸으며 $PIPESTATUS이를 통해 마침내 파이프라인의 모든 종료 상태는 물론 $?원래 Bourne 셸 이후에 있었던 마지막 종료 상태에 액세스할 수 있게 되었습니다. 아마도 비슷한 일이 결국 일어날 것입니다 $!.

답변2

내 생각엔 당신이 제안한 대로 뭔가를 할 수 있을 것 같아요여기.

(ls -l | echo "Hello" | df -h & echo $! >&3 ) 3>pid

위의 예에서는 세 번째 파이프라인 프로세스의 pid를 검색하여 pid 파일에 기록했습니다. 배관 과정을 모두 적을 수 있어요.

답변3

이식성이 떨어지는 Linux 관련 솔루션은 프로세스를 추적하기 위해 프로세스를 연결하는 파이프를 사용하는 것일 수 있습니다. jobs -p파이프라인에서 첫 번째( ) 및 마지막( ) 명령의 PID를 얻을 수 있습니다 . $!PID 중 하나를 사용하여 이 스크립트는 작업을 수행합니다.

#! /bin/bash

PROC=$1
echo $PROC

if [[ $(readlink /proc/$PROC/fd/1) =~ ^pipe: ]]
then
    # Assuming first process in chain...
    NEXT_FD=1
elif [[ $(readlink /proc/$PROC/fd/0) =~ ^pipe: ]]
then
    # Last process in chain...
    NEXT_FD=0
else
    # Doesn't look like a pipe.
    exit
fi

NEXT_PROC_PIPE=$(readlink /proc/$PROC/fd/$NEXT_FD)

while [[ $NEXT_PROC_PIPE =~ ^pipe: ]] 
do
    PROC=$(find /proc/*/fd -type l -printf "%p/%l\n" 2>/dev/null | awk -F'/' '($6 == "'"$NEXT_PROC_PIPE"'") && ($3 != "'$PROC'" ) {print $3}')
    NEXT_PROC_PIPE=$(readlink /proc/$PROC/fd/$NEXT_FD)
    echo $PROC
done

답변4

이 코드에서는 0부터 시작하는 배열을 사용하고 있습니다. 단지 당신이 통과하는 것을 조심하세요 eval.

#!/bin/bash

cmd=('sleep 10' 'sleep 2' 'sleep 5')
first=1
for c in "${cmd[@]}"; do
  ((first)) && { pipe=$c; first=0; } || pipe+='|'$c
done
shopt -u lastpipe
eval $pipe &

printf 'Pipe:\n%s\n\n' "$pipe"

shellpid=$BASHPID
parent=$(ps -o pid= --ppid $shellpid | head -n -1)
declare -a pids=()
mapfile -t pids < <(printf '%s\n' $(ps -o pid= --ppid $parent))
printf '%s\n' 'Listing the arrays:'
printf '%2s %6s %s\n' i PID command
for i in "${!cmd[@]}"; do
    printf '%2d %6d %s\n' "$i" "${pids[i]}" "${cmd[i]}"
done

printf '\n%s\n' 'ps listing:'
ps xao pid,ppid,command | head -n 1
ps xao pid,ppid,command | tail | head -n -3

관련 정보