터미널을 닫지 않고 터미널에서 실행중인 스크립트를 종료하는 방법 (Ctrl + C가 작동하지 않음)?


35

다른 여러 프로그램을 호출하고 많은 명령을 실행하는 bash 스크립트를 작성했습니다. 터미널에서이 스크립트를 실행합니다. 이제 스크립트를 죽이고 싶습니다.

누르면 Ctrl + C그것을 잘라하지 않습니다 때로는, 때로는 스크립트가 다른 프로그램을 실행하기 때문에 나는 생각하고, 어떤 이유에 킬 (kill) 신호가 작동하지 않습니다.

그러나 터미널 창을 닫으면 스크립트가 종료됩니다.

실제로 터미널 창을 닫지 않고 터미널 창을 닫는 것과 비슷한 할 수있는 일 (키보드 조합)이 있습니까 (명령 기록, 현재 디렉토리, 출력 기록 등을 잃고 싶지 않습니다)?


8
이러한 경우에 나는 시도Ctrl + z

그리고 Ctrl + z실행 후 :kill -9 $(pgrep -f your_script.sh)
Noam Manos

답변:


38

몇 가지 옵션이 있습니다. 하나는 스크립트를 중지하고 ( CtrlZ) 스크립트 의 PID를 가져 와서 SIGKILL프로세스 그룹에 보내는 것입니다.

쉘에서 명령이 실행될 때, 명령이 시작되는 프로세스와 모든 자식은 동일한 프로세스 그룹 (이 경우 포 그라운드 프로세스 그룹)의 일부입니다. 이 그룹의 모든 프로세스에 신호를 보내려면 프로세스 리더에게 신호를 보냅니다. 를 들어 kill명령, 프로세스 리더는 이렇게 표시된다 :

kill -PID

PID스크립트의 프로세스 ID는 어디에 있습니까 ?

예:

test.sh일부 프로세스를 시작 하는 스크립트 를 고려하십시오 . 쉘에서 실행했다고 가정 해보십시오.

$ ./test.sh

다른 터미널에서

$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
                                                                               ├─sleep(17805)
                                                                               └─yes(17803)

이 경우에 의해 생성 된 프로세스 그룹에 신호를 보내 test.sh려면 다음을 수행하십시오.

kill -INT -17802

-INT전송에 사용되므로이 SIGINT명령은 CtrlC터미널 을 누르는 것과 같습니다 . 보내려면 SIGKILL:

kill -KILL -17802

다른 터미널을 열 수없는 경우에만 스크립트를 중지하면됩니다. 가능하면 pgrepPID를 찾는 데 사용 하십시오.

스크립트가 실행하는 명령 중 하나가 트래핑되어있을 수 있습니다 . SIGINT이것이 CtrlC효과가없는 이유 일 수 있습니다 . 그러나 SIGKILL갇힐 수 없으며 일반적으로 마지막 복원 옵션입니다. 죽이기 전에 SIGTERM( -TERM) 를 시도 할 수 있습니다 . 둘 SIGKILL또는 SIGTERMA와 설정 될 수 없다 키보드 바로 가기 방법이 SIGINT있다.

스크립트에 shebang 줄이 포함되어 있지 않으면이 모든 것이 무례합니다. 에서 이 SO 답변 :

일반적으로 상위 쉘은 스크립트가 동일한 쉘에 대해 작성된 것으로 추측합니다 (최소 Bourne과 유사한 쉘은 / bin / sh를 사용하여 스크립트를 실행하고 bash는이를 bash 서브 프로세스로 실행 함) ...

이 때문에 스크립트가 실행될 때 스크립트 이름이 지정된 프로세스 (또는 명령 줄에 스크립트 이름이있는 프로세스)를 찾지 pgrep못하고 실패합니다.

항상 세방 라인을 사용하십시오.


SIGKILL또는 키보드 조합이 SIGTERM있습니까?
becko

@becko 아니오, 당신은 하나를 설정할 수 없습니다 : superuser.com/a/417991/334516
muru

pgrep test.sh나를 위해 PID를 반환하지 않습니다. 나는 간단한 test.sh를 시도했다 : 실행중인 for i in {1..30}; do sleep 1 echo $i done 동안 다른 터미널에서 test.sh실행 pgrep test.sh되지만 아무것도 반환되지 않습니다. 뭐가 문제 야?
becko

1
@becko 스크립트를 어떻게 실행 했습니까? 또한 시도하십시오 pgrep -f test.sh.
muru

pgrep -f test.sh작동하지 않습니다. 나는 다음과 같이 스크립트를 실행한다./test.sh
becko

6

스크립트와 관련된 프로세스를 알고 있다면 다음을 사용하여 PID를 찾을 수 있습니다.

 ps -A

그런 다음 PID 번호를 사용하여 해당 프로세스를 종료하십시오.

 kill -9 PID_Number

1
너무 복잡합니다. 이 스크립트는 다른 여러 프로그램을 생성하며 이러한 프로그램도 병렬 프로세스를 생성합니다. 이러한 모든 프로세스를 추적하는 것은 매우 어렵습니다. 터미널 창을 닫을 때 발생하는 것과 유사한 더 간단한 솔루션이 있어야합니다.
becko

pkill -P $$
Harris

1

Harris가 말했듯이 특정 프로세스를 훨씬 쉽게 찾을 수있는 대화식 프로세스 브라우저가있는 Kill -9 PID_Number것으로 알려진 패키지를 설치할 수도 있습니다 htop. htop은 killing 프로세스도 지원합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.