경쟁 조건 없이 종료되는 하위 프로세스가 아닌 프로세스에 쉘 명령을 연결하려면 어떻게 해야 합니까?

경쟁 조건 없이 종료되는 하위 프로세스가 아닌 프로세스에 쉘 명령을 연결하려면 어떻게 해야 합니까?

때로는 프로세스가 완료되면 다른 명령을 실행해야 한다는 것을 깨닫습니다. 동일한 쉘에 있는 경우(그리고 -Z를 제어할 수 있음)이미 실행 중인 prog1에 "&& prog2"를 추가할 수 있나요?많은 좋은 솔루션이 제공됩니다. 그러나 그하위 프로세스인 경우에만 작동합니다..

적어도 동일한 사용자 ID를 공유하는 프로세스에 대해서는 상당히 표준적인 관용구가 있는데, 이는 셸에서 다음과 같습니다.

while kill -s 0 $pid 2> /dev/null; do sleep 1; done

/procLinux와 같은 시스템에서는 [ -d /proc/$pid ]대체를 사용하여 kill동일한 사용자 ID 요구 사항을 면제할 수 있습니다.

그러나 둘 다 경쟁 조건이 있습니다. 그 동안 프로세스가 종료될 수 있으며 sleep그런 다음 새 프로세스가 동일한 PID를 얻을 수 있습니다. 따라서 루프는 관심 있는 프로세스가 실제로 종료되었다는 사실을 인식하지 못한 채 계속됩니다.

쉘 스크립트에서 경쟁 조건을 제거하는 방법이 있습니까?

답변1

Linux에 따라 다를 수도 있고 다른 경우에는 /proc다르게 동작할 수도 있지만 Linux에서는 다음과 같이 할 수 있습니다.

(   # subshell to preserve CWD
    cd /proc/$pid || exit
    [ "$expected_path" = "$(readlink exe)" ] || exit # optional, and can do more checks
    while [ -d . ]; do sleep 1; done
)

.프로세스가 종료되면 작업 디렉토리는 더 이상 유효하지 않으며 더 이상 존재하지 않습니다. 그러나 새로운 프로세스가 해당 pid를 채택하면아니요다시 효과적입니다. 프로세스가 이전에 종료된 경우(그리고 pid가 사용되지 않은 상태로 남아 있는 경우) cd이는 cd실패하고 서브쉘이 종료됩니다. 이전에 pid를 재사용했다면 cd성공할 것이지만 "선택적" 검사(LJKims에게 감사드립니다)를 통해 이를 잡을 수 있기를 바랍니다. 따라서 검사가 가능한 경합의 매우 짧은 범위를 포착하는 한 경합 조건은 없습니다. 테스트하려면 다음을 사용할 수 있습니다.

# shell 1
$ sleep 10 &
[1] 26453
$ cd /proc/26453

# shell 2 (must be bash for BASHPID)
for ((i=0; i<200000; ++i)) do ( if [ 26453 -eq $BASHPID ]; then echo "I am have the pid — sleeping 60"; sleep 60; echo "done sleeping"; fi ); done
I have the pid — sleeping 60

# back to shell 1
[ -d . ]; echo $?
1

따라서 새 PID가 26453이더라도 관심 있는 수면이 종료되었음을 여전히 알 수 있습니다.

답변2

프로세스를 중지할 수 있다고 가정하면(예: 언급한 ctrl+를 통해 z) 이는 비경쟁적인 조롱 방법입니다 && prog2(실제로 더 정확하게는 ; prog2종료 상태를 확인하지 않지만 추가할 수 있기 때문입니다).

PID를 찾으세요. 다른 터미널을 열고 실행

strace -f -e trace=exit_group -p $PID && prog2

그런 다음 프로세스를 재개하십시오.

답변3

아마도 PID만을 기반으로 프로세스를 모니터링하고 싶지 않을 것입니다. 즉, 아마도 프로세스가 무엇인지 알고 있을 것입니다. /proc/<pid>/cmdline의 내용을 모니터링하여 내용이 더 이상 존재하지 않거나 예상과 일치하지 않으면 명령/작업을 실행할 수 있습니까?

답변4

어쩌면 파일을 잠그는 것이 좋은 접근 방식일 수도 있습니다. 하위 프로세스에 전달된 문자열을 포함하여 잠금 파일/잠금 파일 이름의 일부에 넣을 수도 있습니다.

잠긴 파일은 프로세스가 실제로 종료되는 과정에서 삭제될 수 있습니다. 그런 다음 이름이나 내용으로 잠금 파일을 찾고 PID를 잠금 파일에 넣을 수 있습니다. 잠금 파일이 있고 여전히 실행 중인 경우 파일에서 PID를 얻을 수 있습니까? 반면에 잠금 파일이 사라지면 프로세스가 완료된 것입니다.

관련 정보