화면을 종료하기 전에 확인하는 방법(명령줄에 종료를 입력하는 경우) 가능합니까?
답변1
나는 exit
함수로 명령을 마스킹하여 이 문제를 해결했습니다. 이 함수는 사용자가 화면 안에 있는지, 그리고 해당 화면 프로세스에 남아 있는 유일한 하위 프로세스인지 확인합니다.
exit() {
if [[ "$(ps -o pid= --ppid "$(ps -o ppid= -p "$$")" | wc -l)" -eq 1 ]]
then
read -p "Warning: you are in the last screen window; do you really want to exit? (y/n) "
case $REPLY in
(y*) command exit "$@" ;;
esac
else
# not within screen at all, or not within the last screen window
command exit "$@"
fi
}
이 기능을 (bash) 구성 파일의 일부로 포함해야 합니다. 즉, ~/.bash_profile
화면을 시작할 때 (달리 지정하지 않는 한) $SHELL 인스턴스를 시작합니다. 쉘은 스크린 프로세스의 하위 프로세스가 됩니다. 하위 쉘에서 종료할 때 위 코드는 현재 쉘의 상위 프로세스의 하위 프로세스 수를 확인합니다. 내부에서 밖으로:
$(ps -o ppid= -p "$$")
--=
현재 프로세스의 상위 PID를 요청합니다(억제 헤더 라인 추가)($$
)$(ps -o pid= --ppid ... | wc -l)
-- 상위 PID가 우리의 상위인 PID 목록(헤더 없이)을 요청한 다음 출력된 행 수를 계산합니다.
우리가 screen 세션의 마지막 자식인 것처럼 보이면 확인 메시지가 표시됩니다. 응답이 문자로 시작하면 y
함수는 "실제" exit
명령을 호출하여 셸을 종료합니다.
우리가 마지막 자식 프로세스가 아닌 경우 함수는 계속 실행되고 정상적으로 종료됩니다.
이것을 개발할 때 주의해야 할 몇 가지 사항이 있습니다.
if
처음에는 스크린 세션에 있는지 확인하기 위해STY
채워졌는지,SHLVL
1보다 큰지 확인하는 등 더 많은 테스트를 수행했습니다 . 화면은 STY를 설정하고 bash는 SLVL을 증가시키지만 이러한 변수 중 어느 것도 읽기 전용이 아니므로 이 테스트는 많이 사용할 만큼 강력하지 않습니다.screen 도
WINDOW
변수를 설정하지만 이를 확인하는0
것은 신뢰할 수 없습니다. 두 개의 창을 연 다음 window 를 닫고0
window 를1
마지막 창으로 남겨 둘 수 있습니다.기본적으로 EOF(보통 Control+ D)를 입력하면 이 래퍼 기능을 우회하여 셸이 즉시 종료됩니다. 내가 아는 가장 좋은 해결 방법은 변수를
IGNOREEOF
0이 아닌 값으로 설정하는 것입니다. 그러나 이는 불가피한 쉘 종료를 지연시킬 뿐입니다.
위에서는 bash(및 GNU procutils) 관련 기능을 많이 사용하고 있기 때문에 POSIX 호환 솔루션도 제공하고 싶었습니다. 이 줄을 특정 상위 PID가 있는 프로세스 수를 캡처하는 시나리오 ps
로 변경합니다. 또 다른 변경 사항은 프롬프트 및 를 ps ... | grep -c
재작업하는 것입니다 .read -p
read
exit() {
parent="$(ps -o ppid= -p $$)"
if [ "$( ps -eo ppid= | grep -c "^ *${parent}\$" )" -eq 1 ]
then
printf "Warning: you are in the last screen window; do you really want to exit? (y/n) "
read REPLY
case $REPLY in
(y*) command exit "$@" ;;
esac
else
# not within screen at all, or not within the last screen window
command exit "$@"
fi
}
답변2
나는 당신이 bash를 사용하고 있다고 가정합니다.
are_u_sure(){
read -n1 -p "Are you sure to exit? [y/N] "
[ "$REPLY" != y ] && { echo; history -a; bash; }
}
trap are_u_sure EXIT
이것을 ~/.bashrc에 추가하면 bash를 종료하려고 할 때마다 메시지가 표시됩니다(exit 또는 ^D 입력). "y"를 누르지 않으면 절대 종료되지 않습니다.
이렇게 하면 bash 범위 내에서 화면 마법을 수행할 수 있으므로 화면 마법에 집착할 필요가 없습니다.
이 방법은 매우 간단하기 때문에 한 가지 단점이 있습니다. 즉, 이전에 입력한 변수 할당을 잃게 됩니다. 하지만 아마도 우리는 그 일을 할 수 있을 것입니다. 어쨌든 필요에 맞게 이 코드를 수정할 수 있습니다.
답변3
나는 내가 본 다른 솔루션에 너무 만족하지 않았기 때문에 결국 다음을 사용하게 되었습니다(.bashrc에 추가됨).
exit_with_prompt() {
printf "Do you really want to exit screen? (y/n) "
read REPLY
case $REPLY in
(y*) command exit "$@" ;;
esac
}
export IGNOREEOF=0
[[ $(type -t exit) == "alias" ]] && unalias exit
[[ $(type -t logout) == "alias" ]] && unalias logout
if grep -q "^screen\b" /proc/$PPID/comm; then
export IGNOREEOF=2
alias exit=exit_with_prompt
alias logout=exit_with_prompt
fi
그런 다음 이것을 .screenrc에 추가하십시오.
shell -$SHELL
제가 평소에 하던 방식이랑 좀 반대네요. 별칭을 설정 해제하고 ctrl-d -> 종료를 다시 활성화하지만 bash가 화면 인스턴스 내에서 즉시 실행되고 있는지 확인합니다(구체적으로 상위 프로세스 명령이 "screen"으로 시작한 다음 단어 경계로 시작하는지 확인합니다). 그런 다음 ctrl-d/EOF 종료를 비활성화하고 종료 및 로그아웃을 위한 프롬프트 별칭을 사용하여 종료를 설정합니다.
오랫동안 사용하지는 않았지만 현재까지는 작동 방식에 매우 만족합니다.