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
와 해당 하위 항목(있는 경우) B
은 C
작업(작업 제어가 활성화된 대화형 셸)에 포함됩니다. 쉘은 첫 번째 무료 작업 번호를 선택합니다. 작업은 다른 보류 중인 작업이 없는 경우에만 현재 작업이 됩니다(// %+
(또는 %%
일부 쉘의 인수에서도 호출됨)) .%
kill
fg
bg
jobs -l
Bash에서는 작업이 알고 있는 프로세스 ID와 함께 작업이 나열됩니다. 종료된 것까지 나열하는 것 같으니(내 테스트에서 실행된 것을 나열하는 것은 true
버그처럼 보임) 거기에서 볼 수 있을 것입니다. 하지만 이를 안정적으로 수행하는 것은 불가능합니다.Running
sleep 100 | true
$!
zsh
$jobstates
키가 작업 ID와 값인 특수 연관 배열을 사용하면 더 나은 행운을 누릴 수 있습니다 .running:+:37632=running:37633=done
job_id=${(k)jobstates[(R)*:$!=*]}
여기에서 값이 발견된 요소가 발견됩니다 :$!=
. 가능성은 희박하지만 프로세스가 종료되고 해당 부모가 종료를 확인한 후에 두 작업이 동일한 pid를 갖는 것이 불가능하지 않다는 점을 명심하세요.
이제 이것을 갖고 나면 job_id
job_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