zsh를 bash처럼 동작하게 만드는 방법이 있습니까 jobs -p
? 주다
오직숫자, 그런 사람은 무엇을 할 수 있습니까 kill $(jobs -p)
?
답변1
jobs
작업에 대한 보고서, 작업에는 여러 프로세스가 있을 수 있습니다.
대화형인 경우 작업은 프로세스 그룹에 배치되므로 전체적으로 일시 중지/재개/중단될 수 있습니다.
jobs -p
(및 zsh
)는 bash
작업에 있는 모든 프로세스의 프로세스 ID가 아닌 각 작업의 프로세스 그룹 ID를 반환합니다.
쉘이 (작업 제어 없이) 대화형으로 실행되지 않는 경우, 쉘은 작업 제어가 있는 경우 프로세스 그룹 리더가 되는 프로세스의 pid를 보고합니다( $!
btw로 반환되는 것과 다를 수 있음).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh는 pgid 29643의 작업 2에 대해 zsh가 2개의 프로세스를 시작했으며 그 중 하나는 완료되었고 다른 하나는 여전히 실행 중이라고 보고합니다.
에서와 같은 pgid를 얻으려면 bash
파이프를 통해 이를 수행할 수 있습니다.
awk '/^\[/{print $3}'
작업 내에서 pid를 얻으려면(셸에서 시작된 pid만) $jobstates
특수 연관 배열을 보면 됩니다.
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
작업 1에서 아직 실행 중인 프로세스의 pid를 추출하려면 다음을 수행하세요.
$ echo ${${(M)${(s/:/)jobstates[1]}:#*=running}%=*}
29644
이제 이러한 작업을 종료하려면 프로세스 그룹(대화형 셸에서), 즉 작업 내의 임의 프로세스가 아닌 전체 작업을 종료해야 합니다.
이를 사용하여 ID가 29643인 프로세스 그룹을 종료할 수 있습니다 kill -- -29643
.kill 29643
프로세스ID 29643(위 예에서는 유효하지 않음)
여기서는 pid 또는 pgid(비대화형 쉘에서는 작동하지 않음) 대신 kill할 작업 번호를 전달하는 것이 더 합리적입니다. 작업 번호는 다음과 같습니다.
kill %${(k)^jobstates}
bash
불행하게도 믿을만한 동등한 제품이 없다고 생각합니다 .
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
이들로부터 작업 번호를 안정적으로 추출하는 것은 어렵습니다. (나는 또한 while kill %; do continue; done
경쟁 조건 버그처럼 보이는 것 때문에 작동하지 않는다는 것을 알았습니다 ).
대화형이 아닌 실행 시에는 작업 제어가 없으므로 kill %1
작업 번호 1을 종료하면 해당 작업에는 프로세스 그룹이 없습니다. 따라서 가난한 사람의 근사치로 쉘 ( bash
및 zsh
)은 모든 프로세스를 종료합니다그것은 알고 있다대신 혼자. 위의 예에서는 대신 다음을 수행합니다.
kill(-29643, SIGTERM);
그것은 할 것입니다:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
이 두 프로세스가 자체적으로 생성된 다른 프로세스는 종료되지 않지만(있는 경우) 접근 방식 처럼 kill $(jobs -p)
29643을 종료하는 것보다 여전히 낫습니다 .