nohup을 사용하여 호출된 스크립트는 호출 스크립트가 종료될 때 때때로 종료됩니다.

nohup을 사용하여 호출된 스크립트는 호출 스크립트가 종료될 때 때때로 종료됩니다.

screenshot-menu.bash스크린샷 메뉴( ) 를 표시하는 작은 bash 스크립트를 작성했습니다 .

#!/usr/bin/env bash
echo 'Select an option:

s whole screen
w active window
r select region
'
read -rsn1 key
sleep 0.1

case $key in
  s|w|r) nohup ./screenshot.bash -$key & ;;
  *) echo Canceled. >> ./log.txt ;;
esac

스크립트는 nohup ./screenshot.bash매개변수를 사용하여 실행됩니다. 이것은 screenshot.bash:

#!/usr/bin/env bash
while [[ "$#" > 0 ]]; do case $1 in
  -s|--screen) PARAM=''; TYPE='Screen'; shift;;
  -w|--window) PARAM='-u'; TYPE='Window'; shift;;
  -r|--region) PARAM='-s'; TYPE='Region'; shift;;
  *) echo "Unknown parameter passed: $1"; exit 1; shift; shift;;
esac; done

sleep 0.2
scrot $PARAM $(xdg-user-dir PICTURES)/'%Y-%m-%d %H.%M.%S $wx$h '$TYPE.png -e 'echo "$f" && notify-send -u low "$f"'

./screenshot-menu.bash터미널 내에서 실행한 다음 를 입력 하면 r모든 것이 잘 작동합니다. 영역을 선택하고 해당 영역의 스크린샷을 얻을 수 있습니다.

하지만 저는 이 스크립트를 어디에서나 호출할 수 있기를 원합니다. 이것이 바로 새 터미널 창에서 이 스크립트를 실행하기 위한 키 바인딩이 있는 이유입니다.

alacritty -t "Screenshot menu" -o "window.dimensions.columns=20" -o "window.dimensions.lines=7" -e ~/bin/screenshot-menu.bash

(또는 더 간단합니다 gnome-terminal -- ~/bin/screenshot.bash.)

이것이 제가 사용하는 것입니다 nohup. 스크린샷에 표시되는 것을 원하지 않기 때문에 터미널을 종료하고 싶습니다. 하지만 물론 screenshot.bash죽지는 않았습니다.

두 번째 방법(새 터미널 창에서 스크립트 작성)은 5번에 한 번씩 작동할 수 있습니다. 다른 경우에는 영역을 선택할 때 커서가 십자선으로 바뀌지 않습니다. screenshot.bash사용해도 죽은 줄 알았 습니다 nohup.

이 무작위 동작의 원인은 무엇입니까?

답변1

문제는 screenshot-menu.bash백그라운드 포크에서 실행 중인 프로세스가 실행되기 전에 a를 받고 종료될 가능성이 높습니다.nohup ./screenshot.bash -$keySIGHUPnohup

간단한 실험을 통해 이를 확인할 수 있습니다.

$ alacritty -e sh -c 'nohup sleep 1000 &'
$ pgrep -a sleep
$

strace전체 명령은 분기를 표시하지만 분기 프로세스가 분기를 수신하고(종료되고 생성된 의사 터미널이 사라지면) 종료될 때까지 실행 sh되지 않습니다 execve.nohupSIGHUPalacritty

터미널과 그래픽 응용 프로그램을 혼합할 때 존재할 수 있는 대안을 찾지 않고 합리적인 해결책은 nohup백그라운드로 이동하는 명령에 적용하는 것을 피하고 대신 상위 프로세스에서 사용하는 것입니다. 예를 들어:

$ alacritty -e sh -c 'nohup sh -c "sleep 1000 &"'
$ pgrep -a sleep
625910 sleep 1000

screenshot-menu.bash이 줄을 적절하게 변경할 수 있습니다

s|w|r) nohup ./screenshot.bash -$key & ;;

입력하다

s|w|r) nohup sh -c "./screenshot.bash \"-$key\" &" ;;

또는 screenshot-menu.bash작업 제어를 활성화하고 set -m제거 할 수 있습니다 nohup(쉘은 자체 프로세스 그룹에서 백그라운드 파이프(간단한 명령도 파이프)를 시작하고 SIGHUP터미널을 제어하는 ​​경우 포그라운드 프로세스 그룹만 전달됩니다)가 사라집니다. , screenshot.bash터미널에서 읽거나 쓰려는 시도가 없는지 확인할 수 있는 경우 (즉, 수행한 것과 동일한 명시적인 리디렉션이 필요함 nohup)

예를 들어 screenshot-menu.bash다음과 같을 수 있습니다.

#!/usr/bin/env bash

set -m

echo 'Select an option:
...
'

case $key in
  s|w|r) </dev/null >>./log.txt 2>&1 ./screenshot.bash "-$key" & ;;
  *) echo Canceled. >>./log.txt ;;
esac

또한보십시오:

관련 정보