내 손에 PID가 있다고 가정해 보세요.mypid=$$
주어진 pid를 가진 프로세스의 종료를 수신하는 데 사용할 수 있는 bash/시스템 명령이 있습니까?
mypid에 프로세스가 없으면 명령이 실패해야 한다고 생각합니다.
답변1
이 답변에서 필요한 것을 얻었습니다.https://stackoverflow.com/a/41613532/1223975
..사용된 결과wait <pid>
pid가 현재 프로세스의 하위 프로세스인 경우에만 유효합니다..
그러나 다음 사항은 모든 프로세스에 적용됩니다.
프로세스가 완료될 때까지 기다립니다.
리눅스:
tail --pid=$pid -f /dev/null
다윈( $pid
파일 열기 필요):
lsof -p $pid +r 1 &>/dev/null
시간 초과(초) 있음
리눅스:
timeout $timeout tail --pid=$pid -f /dev/null
다윈( $pid
파일 열기 필요):
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
답변2
이식 가능한 방법은 폴링을 위해 kill을 사용하는 것입니다. 즉, 다음과 같습니다.
until kill -s 0 "$pid" 2>/dev/null; do sleep 1; done
여기에는 GNU tail 또는 lsof와 같은 이식 불가능한 명령이 필요하지 않으며 bash에서는 sleep이라는 외부 명령 하나만 호출됩니다. GNU tail은 아마도 C로 작성되었기 때문에(예를 들어 이론적으로 더 높은 수준의 기능을 활용할 수 있음) 좀 더 효율적일 것이며 pidfd_open
lsof는 많은 오버헤드를 가질 수 있습니다.
루프 반복 횟수를 계산하여 대략적인 시간 초과를 달성할 수 있습니다.
하나의 웨이터에서만 작동하는 약간 덜 이식성 있는 솔루션은 ptrace(2)를 사용하는 것입니다. 이는 이식 가능한 쉘 인터페이스는 없지만 일부 시스템에서 strace 명령을 사용하여 액세스할 수 있습니다.
strace -e exit -e signal=none -p "$pid"
답변3
Bash 내장 명령을 사용할 수 있습니다 wait
.
$ sleep 10 &
[2] 28751
$ wait 28751
[2]- Done sleep 10
$ help wait
wait: wait [-n] [id ...]
Wait for job completion and return exit status.
Waits for each process identified by an ID, which may be a process ID or a
job specification, and reports its termination status. If ID is not
given, waits for all currently active child processes, and the return
status is zero. If ID is a a job specification, waits for all processes
in that job's pipeline.
If the -n option is supplied, waits for the next job to terminate and
returns its exit status.
Exit Status:
Returns the status of the last ID; fails if ID is invalid or an invalid
option is given.
시스템 호출을 사용합니다 waitpid()
..
$ whatis waitpid
waitpid (2) - wait for process to change state
답변4
~에 대한https://stackoverflow.com/a/41613532/1223975Alexander Mills가 다시 게시한 솔루션은 Timeout in Seconds
Darwin
GNU가 없는 UNIX 계열 운영 체제에 대한 해결 방법입니다 tail
. 에 국한된 것은 아니지만 Darwin
UNIX 계열 운영 체제의 수명에 따라 제공된 명령줄이 필요 이상으로 복잡하여 실패할 수 있습니다.
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
하나 이상의 이전 UNIX에서 이 lsof
매개변수가 +r 1m%s
실패합니다(수퍼유저의 경우에도).
lsof: can't read kernel name list.
m%s
출력 형식 사양입니다 . 더 간단한 후처리기에는 필요하지 않습니다. 예를 들어, 다음 명령은 PID 5959에서 최대 5초 동안 기다립니다.
lsof -p 5959 +r 1 | awk '/^=/ { if (T++ >= 5) { exit 1 } }'
${?}
이 예에서는 PID 5959가 5초가 경과하기 전에 자체적으로 종료되는 경우입니다 0
. ${?}
5초 후에도 반환되지 않는 경우 .1
+r 1
의 는 1
폴링 간격(초)이므로 상황에 맞게 변경할 수 있다는 점도 주목할 가치가 있습니다 .