에 있는 경우 bash
다음을 실행합니다.
cmd1 | cmd2 | ... | cmdi | ... | cmdn &
명확하지 않을 수도 있습니다 cmd{1..n}
. PID를 어떻게 얻나요 cmdi
? 아니면 어떻게 cmdi
프로세스에 신호를 보낼 수 있나요? (예: 보내기 SIGUSR1
?)
pkill
/ pgrep
etc는 동일한 파이프라인의 일부를 포함하여 다른 인스턴스가 실행 중일 수 있으므로 pidof
좋은 대답이 아닌 것 같습니다 . 의 PID를 알려 cmdi
주세요 .jobs -p
cmd1
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