Ctrlc완료하는 데 오랜 시간이 걸리는 프로세스를 중단하려고 쉘에서 두 번 누르십시오 .
^C
두 번 에코되었지만 프로세스는 계속 진행되었습니다.
Ctrlc평소처럼 프로세스를 종료 하지 않은 이유는 무엇 입니까?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
. 아마도 다른 신호 인 SIGSTOP을 생각하고있을 것입니다.
Ctrlc완료하는 데 오랜 시간이 걸리는 프로세스를 중단하려고 쉘에서 두 번 누르십시오 .
^C
두 번 에코되었지만 프로세스는 계속 진행되었습니다.
Ctrlc평소처럼 프로세스를 종료 하지 않은 이유는 무엇 입니까?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
. 아마도 다른 신호 인 SIGSTOP을 생각하고있을 것입니다.
답변:
프로세스는 다음을 선택할 수 있습니다.
trap '' INT
하거나 종료하지 않기로 결정하거나 적시에 종료하지 못하는 자체 처리기가 있습니다.stty int '^K'
쉘에서 와 같이 )이라고 말하십시오.stty -isig
쉘에서 와 같이 ).또는 중단 될 수없는 시스템 호출 도중과 같이 중단 할 수 없습니다.
Linux (상대적으로 최신 커널 사용)에서 프로세스가 SIGINT를 무시하거나 처리 하고 있는지 여부를 알 수 있습니다.
$ kill -l INT
2
$ grep Sig "/proc/$pid/status"
SigQ: 0/63858
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 0000000000000000
SIGINT는 2입니다. 위의 SigIgn의 두 번째 비트는 1이며 SIGINT는 무시됩니다.
다음을 사용하여이를 자동화 할 수 있습니다.
$ SIG=$(kill -l INT) perl -lane 'print $1 if $F[0] =~ /^Sig(...):/ &&
$F[1] & (1<<($ENV{SIG}-1))' < "/proc/$pid/status"
Ign
현재 intr
문자가 무엇인지 또는 isig
주어진 터미널에 대해 활성화되어 있는지 확인하려면 :
$ stty -a < /dev/pts/0
[...] intr = ^C [...] isig
(위의 intr
문자는 ^C
(프레스 CTRL-C및 입력 신호가 비활성화되지 않은 경우 (일반적으로 터미널 (에뮬레이터)가 전송 한 문자) 입니다.)
$ stty -a < /dev/pts/1
[...] intr = ^K [...] -isig
( intr
문자는 ^K
이며 isig
비활성화되어 있습니다 /dev/pts/1
).
완전성을 위해 프로세스가 SIGINT 수신을 중지하기 위해 수행 할 수있는 다른 두 가지 방법이 있지만 일반적으로 볼 수있는 것은 아닙니다.
되면 Ctrl+C상기 SIGINT 신호는 상기 공정 모두에 전송되는 단말기의 전경 프로세스 그룹 . 프로세스 그룹에 프로세스를 배치하고 (쉘 작업에 맵핑 된) 일반적으로 쉘 은 터미널 디바이스에 포 그라운드 디바이스를 알려줍니다 .
이제 프로세스는 :
프로세스 그룹을 떠나십시오. 다른 프로세스 그룹 (프로세스 그룹이지만 포 그라운드 그룹 인 프로세스 그룹 )으로 이동하면 더 이상 SIGINT를받지 못합니다 Ctrl-C(SIGTSTP, SIGQUIT와 같은 다른 키보드 관련 신호). 그러나 (백그라운드 프로세스처럼) 터미널 장치에서 읽기를 시도하면 (터미널 장치 설정에 따라 쓸 수도 있음) 일시 중단 될 수 있습니다.
예로서:
perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
와 (과) 중단 할 수 없습니다 Ctrl-C. 위 perl
의 ID는 부모 프로세스 ID와 동일한 프로세스 그룹에 참여하려고합니다. 일반적으로 해당 ID를 가진 프로세스 그룹이 있다는 보장은 없습니다. 그러나 여기서 perl
대화식 쉘 프롬프트에서 해당 명령을 자체적으로 실행 하는 경우 ppid는 쉘의 프로세스가되고 일반적으로 쉘은 자체 프로세스 그룹에서 시작됩니다.
명령이 아직 프로세스 그룹 리더 (포 그라운드 프로세스 그룹의 리더)가 아닌 경우 새 프로세스 그룹을 시작하면 동일한 효과가 나타납니다.
예를 들어 쉘에 따라
$ ps -j >&2 | perl -MPOSIX -e 'setpgid(0,0) or die "$!"; sleep 10'
PID PGID SID TTY TIME CMD
21435 21435 21435 pts/12 00:00:00 zsh
21441 21441 21435 pts/12 00:00:00 ps
21442 21441 21435 pts/12 00:00:00 perl
같은 효과가 있습니다. ps
및 perl
전경 프로세스 그룹에서 시작되지만, 대부분의 쉘에 ps
합니다 (에서와 같이 해당 그룹의 리더가 될 것 ps
양쪽의 pgid를하는 위 출력 ps
하고 perl
의 PID입니다 ps
) 그래서, perl
자신의 프로세스 그룹을 시작할 수 있습니다.
또는 포 그라운드 프로세스 그룹을 변경할 수 있습니다. 기본적으로 tty 장치에 SIGINT를 다른 프로세스 그룹에 보내도록 지시하십시오.Ctrl+C
perl -MPOSIX -e 'tcsetpgrp (0, getppid) 또는 die $ !; 수면 5 분
거기에는 perl
동일한 프로세스 그룹이 남아 있지만 대신 포 그라운드 프로세스 그룹이 상위 프로세스 ID와 동일한 그룹임을 터미널 장치에 알리고 있습니다 (위의 참고 참조).
hdparm
하거나 smartctl
결함이있는 하드 디스크 를 사용 하면 영구적으로 중단되며 CTRL + C를 사용하여 종료 할 수 없습니다. 프로세스의 합계 열을보고 무정전 수면에있는 경우 알 수 있습니다 ps aux
또는의 S 칼럼에서 top
/ htop
- D
수단 무정전 수면. 이것은 반드시 나쁜 것은 아니지만 프로세스가 많은 IO를 수행하고 있음을 의미 할 수 있습니다.
kill -9 %
죽이는 것입니다. 신호 9는 무시할 수 없으며 일시 중단 신호도 마찬가지입니다. CTRL + Z 키보드 순서는 이론상 무시할 수 있지만 실제로는 그렇지 않습니다.