Bash에서 새로운 백그라운드 프로세스의 작업 ID를 프로그래밍 방식으로 얻는 방법

Bash에서 새로운 백그라운드 프로세스의 작업 ID를 프로그래밍 방식으로 얻는 방법

Bash에서 로 시작하는 작업의 작업 ID를 프로그래밍 방식으로 어떻게 얻습니까 &?

백그라운드에서 작업을 시작한 &다음 해당 작업 ID 및 Bash 내장 명령(예 fg: bg, 등)을 사용하여 kill작업과 상호 작용할 수 있습니다 .

예를 들어 내가 이런 일을 시작한다면

yes > /dev/null &

그런 다음 다음 명령을 사용하여 해당 작업을 종료할 수 있습니다(작업이 작업 ID 1을 얻는다고 가정).

kill %1

create a new job을 사용할 때 &새로 생성된 작업의 작업 ID를 프로그래밍 방식으로 어떻게 얻을 수 있습니까 ?


난 네가 얻을 수 있다는 걸 알아프로세스 번호(작업 ID 아님) $!, 특히 작업 ID를 얻는 방법을 알고 싶습니다.

답변1

이 명령은 jobs현재 실행 중인 백그라운드 작업과 해당 ID를 인쇄합니다.

$ for i in {1..3}; do yes > /dev/null & done
[1] 3472564
[2] 3472565
[3] 3472566

$ jobs
[1]   Running                 yes > /dev/null &
[2]-  Running                 yes > /dev/null &
[3]+  Running                 yes > /dev/null &

따라서 아직 실행 중인 마지막으로 시작된 작업의 ID를 얻으려면다음과 같이 표시됩니다.+, 다음을 수행할 수 있습니다(GNU 사용 grep).

$ jobs | grep -oP '\d(?=]\+)'
3

또는 더 휴대성이 뛰어납니다.

$ jobs | sed -n 's/^\[\([0-9]*\)\]+.*/\1/p'

그러나 작업 중 하나를 일시 중지하면 해당 작업이 대신하게 되므로 +마지막 행만 가져오는 것이 좋습니다.

$ jobs | tail -n1 | cut -d' ' -f1 | tr -d '][+'
3

답변2

bash 매뉴얼에서 인용 :

셸에서 작업을 참조하는 방법에는 여러 가지가 있습니다. % 문자는 작업 사양(jobspec)을 나타냅니다. 작업 번호 n은 %n이라고 할 수 있습니다. 작업을 시작하는 데 사용된 이름의 접두사를 사용하거나 해당 명령줄에 나타나는 하위 문자열을 사용하여 작업을 참조할 수도 있습니다. 예를 들어 %ce는 중지된 ce 작업을 나타냅니다. 접두사가 둘 이상의 작업과 일치하면 bash는 오류를 보고합니다. 반면, %?ce를 사용하면 명령줄에 ce 문자열이 포함된 모든 작업을 나타냅니다. bash는 하위 문자열이 둘 이상의 작업과 일치하는 경우 오류를 보고합니다. %% 및 %+ 기호는 현재 작업, 즉 포그라운드에서 중지되었거나 백그라운드에서 시작된 마지막 작업에 대한 쉘의 개념을 나타냅니다. %-를 사용하여 이전 작업을 참조할 수 있습니다. 작업이 하나만 있는 경우 %+ 및 %-를 모두 사용하여 해당 작업을 참조할 수 있습니다. 작업 관련 출력(예: jobs 명령의 출력)에서 현재 작업은 항상 +로 표시되고 이전 작업은 -로 표시됩니다. 단일 %(수반되는 작업 사양 없음)도 현재 작업을 나타냅니다.

또한 이 명령은 jobs -l작업 ID와 PID를 나열하므로 $!일부 스크립트를 사용하여 PID(가져옴)를 작업 ID로 변환할 수 있습니다.

답변3

cmd &작업 번호를 재사용할 수 있으며, 프로세스 ID와 프로세스 그룹 ID를 재사용할 수 있습니다. 호출 사이에 job실행 중인 프로세스가 cmd종료되지 않는다는 보장은 없습니다 .

에서는 일반적으로 bash의 출력을 jobs사후 처리할 수 없습니다.

당신이 믿을 수 있는 것은 그 이후이다.

A | B | C &

trap파이프를 비동기식으로 시작 하지 않은 경우 $!실행을 시작한 프로세스의 pid가 포함됩니다 C.

실행 중인 프로세스 A와 해당 하위 항목(있는 경우) BC작업(작업 제어가 활성화된 대화형 셸)에 포함됩니다. 쉘은 첫 번째 무료 작업 번호를 선택합니다. 작업은 다른 보류 중인 작업이 없는 경우에만 현재 작업이 됩니다(// %+(또는 %%일부 쉘의 인수에서도 호출됨)) .%killfgbg

jobs -lBash에서는 작업이 알고 있는 프로세스 ID와 함께 작업이 나열됩니다. 종료된 것까지 나열하는 것 같으니(내 테스트에서 실행된 것을 나열하는 것은 true버그처럼 보임) 거기에서 볼 수 있을 것입니다. 하지만 이를 안정적으로 수행하는 것은 불가능합니다.Runningsleep 100 | true$!

zsh$jobstates키가 작업 ID와 값인 특수 연관 배열을 사용하면 더 나은 행운을 누릴 수 있습니다 .running:+:37632=running:37633=done

job_id=${(k)jobstates[(R)*:$!=*]}

여기에서 값이 발견된 요소가 발견됩니다 :$!=. 가능성은 희박하지만 프로세스가 종료되고 해당 부모가 종료를 확인한 후에 두 작업이 동일한 pid를 갖는 것이 불가능하지 않다는 점을 명심하세요.

이제 이것을 갖고 나면 job_idjob_id가 재사용될 가능성이 높으므로 이를 사용하기 전에 백그라운드에서 다른 작업이 시작되거나 일시 중지되지 않았는지 확인해야 합니다.

작업 ID에 의존하는 대신 작업 이름에 고유한 문자열을 삽입하고 이를 참조할 수 있습니다 %?that-string.

예를 들어:

sleep 100 | sleep 101 $(: first) &
sleep 123 | sleep 123 $(: second) &
kill '%?first'

프로세스가 실행되는 동안 작업이 종료됩니다 sleep 100. sleep 101작업이 계속 실행 중이고 실행 시 두 프로세스가 모두 종료되면 오류가 kill발생합니다 .kill: %?first: no such job

관련 정보