( /programming/13718394/what-should-interactive-shells-do-in-Olone-process-groups 의 제안에 따라 유닉스에 다시 게시 )
짧은 질문은 쉘이 tty를 소유하지 않는 고아 프로세스 그룹에있는 경우 어떻게해야합니까? 그러나 나는 긴 질문을 즐겁게 읽는 것이 좋습니다.
다음은 좋아하는 쉘을 사용하여 랩톱을 휴대용 공간 히터로 전환하는 재미 있고 흥미로운 방법입니다 (만약 tcsh 기괴한 사람이 아닌 경우).
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
이로 인해 bash는 CPU를 100 %로 페그합니다. zsh와 fish는 똑같이 작동하지만 ksh와 tcsh는 작업 제어에 대해 무언가를 뒤섞은 다음 용감합니다. 아, 그리고 플랫폼에 구애받지 않는 범죄자입니다. OS X와 Linux가 모두 영향을받습니다.
내 (잠재적으로 잘못된) 설명은 다음과 같습니다. 자식 쉘이 포 그라운드에 있지 않다는 것을 감지합니다 tcgetpgrp(0) != getpgrp()
. 따라서 스스로 중지하려고 시도합니다 killpg(getpgrp(), SIGTTIN)
. 그러나 부모 (C 프로그램)가 리더이고 사망 SIGTTIN
하여 고아 프로세스 그룹으로 전송 되었기 때문에 프로세스 그룹이 고아입니다. 그렇지 않으면 다시 시작할 수 없습니다. 따라서 자식 셸은 중지되지 않지만 여전히 백그라운드에 있으므로 즉시 다시 수행됩니다. 헹구고 반복하십시오.
제 질문은 커맨드 라인 셸이 어떻게이 시나리오를 감지 할 수 있으며 어떻게해야합니까? 두 가지 솔루션이 있는데 둘 다 이상적이지 않습니다.
- pid가 그룹 ID와 일치하는 프로세스를 알리십시오. 로 실패하면
ESRCH
아마도 고아 일 것입니다. - 에서 1 바이트의 비 차단 읽기를 시도하십시오
/dev/tty
. 로 실패하면EIO
아마도 고아 일 것입니다.
(이 문제를 추적하는 문제는 https://github.com/fish-shell/fish-shell/issues/422입니다 )
당신의 생각에 감사드립니다!