대화형 콘솔에서 를 눌러 Zenity 창을 ^C
닫습니다 . 스크립트에서만 사용할 zenity --info & fg
수 있습니다 . zenity --info & wait
단, ^C
이 경우 Zenity 창은 닫히지 않습니다. 좀 더 일 wait
처럼 행동할 수 있는 방법이 있나요 ?fg
^C
답변1
당신이 할 수 있는 가장 간단한 일은 SIGINT
처리기에서 백그라운드 프로세스를 잡아서(^C) 죽이는 것입니다:
#! /bin/sh
trap 'kill "$!"; exit 1' INT QUIT
zenity --info &
wait
바라보다이것그리고 기타 유사한답변이 행동에 대한 설명.
일부 쉘에서 스크립트를 호출할 때, 예를 들어 bash
소위"기다리고 협력해서 나가세요"(바라보다여기논의를 위해) 신호를 받은 후 프로그램이 완전히 종료되도록 예상되는 방법은 핸들러를 재설정한 다음 동일한 신호로 자체 종료하는 것입니다.
#! /bin/sh
termsig(){ trap - "$1"; kill "$!"; kill -s "$1" "$$"; }
trap 'termsig INT' INT
trap 'termsig QUIT' QUIT
zenity --info &
wait
물론, 이 모든 것은 매우 조잡하며 zenity
자체 생성될 수 있는 하위 프로세스에서는 아무 작업도 수행하지 않으며 여러 백그라운드 프로세스에 맞게 조정해야 합니다. 보다 확실한 해결책은 (trap - INT; zenity --info) &
다음과 같습니다.아니요/bin/sh
Debian 파생 배포판(Ubuntu 등) 또는 busybox 기반 시스템에서 작동합니다.
SIGINT
또 다른 해결책은 구성을 기본값으로 재설정 할 수 있는 래퍼를 통해 프로그램을 실행하는 것입니다 . 그리고 perl
:
#! /bin/sh
perl -e '$SIG{INT} = $SIG{QUIT} = "DEFAULT"; exec @ARGV' zenity --info &
wait
perl
하지만 그렇게 하면 또는 python
;-)를 사용하여 전체 스크립트를 다시 작성할 수도 있습니다.
답변2
비대화형에서는 sh
명령이 비동기적으로 실행되고 &
SIGINT 및 SIGQUIT 신호가 무시됩니다.
tcsetpgrp()
이는 터미널 작업 제어(...)가 존재하지 않았던 시절로 거슬러 올라가는 POSIX 요구 사항입니다. 요즘은 방해가 되는 경우가 많습니다.
동일한 소스의 또 다른 POSIX 요구 사항은 셸이 시작될 때 신호가 무시되면 신호를 무시하지 않는 데 사용할 수 없다는 것입니다 trap
. 다시 말하지만, 요즘에는 이는 환영받지 못하고 짜증나는 행동입니다.
zsh
후자의 요구 사항은 부분적으로만 구현됩니다. trap - SIGNAL
기본 구성 복원 SIGNAL
은 무시되지만 SIGNAL trap handler SIGNAL
설치는 handler
시작 시 신호가 무시되더라도 실제로 .a를 사용하려는 경우 기본 구성을 복원할 수 있습니다 trap : SIGNAL; trap - SIGNAL
.
스크립트에서 SIGINT가 무시되지 않는 한(예: 스크립트가 백그라운드에서 실행 중인 경우) 다음을 수행할 수 있습니다.
#! /bin/sh -
(trap - INT QUIT; exec zenity) & wait
SIGINT 및 SIGQUIT의 기본 구성을 복원합니다.
하지만,POSIX가 작동해야 한다고 명시적으로 말하지만, 일부 구현이 필요하지 않습니다 sh
. 특히, dash
대부분의 다른 파생 ash
상품 에는 적용되지 않습니다 ksh93
. 따라서 이 경우 she-bang을 POSIX 호환 쉘로 변경 하거나 POSIX 호환 쉘이 있는지 확인하는 것이 좋습니다.bosh
yash
#! /bin/bash -
#! /bin/zsh -
#! /bin/mksh -
zsh
쉘 시작 시 SIGINT가 무시되면 다음 명령을 사용하여 구성을 복원 해야 합니다 .
#! /bin/zsh -
trap : INT QUIT # noop handler to unignore
trap - INT QUIT # restore default disposition for the shell
(trap - INT QUIT; zenity) & wait
예(여기 Linux에서는 신호 구성이 비트맵으로 노출됩니다 /proc/<pid>/status
):
$ sh -c 'grep SigIgn /proc/self/status'
SigIgn: 0000000000000000
$ sh -c 'grep SigIgn /proc/self/status & wait'
SigIgn: 0000000000000006 # (1<<(SIGINT-1) | 1<<(SIGQUIT-1))
$ zsh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000
$ bash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000
$ mksh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000
$ dash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ ksh93 -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ yash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ bosh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000100006 # also SIGTTIN
$ (bash -c 'grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000006
$ (bash -c 'trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000006
$ (zsh -c 'grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000002 # not sure why the SIGQUIT was unignored
$ (zsh -c 'trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000002
$ (zsh -c 'trap : INT QUIT; trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000000