SIGSTOP이 스크린 세션 내에서 작동하지 않는 이유는 무엇입니까?

SIGSTOP이 스크린 세션 내에서 작동하지 않는 이유는 무엇입니까?

다음 스크립트를 고려해보세요.

#!/bin/bash
OFILE='log'
echo 'ok' > ${OFILE}
kill -SIGSTOP $$
echo 'after stop' > ${OFILE}

대화형 셸에서는 스크립트가 중지되고 출력은 ok. 그러나 다음과 같이 시작되면

screen -d -m ./test.sh

출력은 입니다 after stop. 화면이 신호를 처리합니까? 스크린 세션에서 프로세스를 일시 중단하는 방법은 무엇입니까?

답변1

아마도 화면 프로세스가 중지된 bash 프로세스를 다시 시작하는 중일 것입니다. 다음을 시도했습니다(두 프로세스 모두에 SIGSTOP 신호 보내기).

test.sh

#!/bin/bash
OFILE='log'
echo 'ok' > ${OFILE}
echo 'screen pid ' $(screen -list | grep sc_test | cut -f1 -d'.' | sed 's/\W//g') >> ${OFILE}
echo 'test.sh pid ' $$ >> ${OFILE}
kill -SIGSTOP $(screen -list | grep sc_test | cut -f1 -d'.' | sed 's/\W//g')
kill -SIGSTOP $$
echo 'after stop' >> ${OFILE}

화면 명령

screen -dmS sc_test ./test.sh

로그 파일

ok
screen pid  4453
test.sh pid  4454

목록 화면

screen -list
There is a screen on:
        4453.sc_test    (11/05/2015 10:45:20 AM)        (Detached)
1 Socket in /var/run/screen/S-root.

답변2

시험GNU 화면-4.0.2의 소스 코드화면은 하위 프로세스가 중지되었는지 확인한 다음 SIGCONT를 사용하여 재개하려고 시도하는 것을 보여주었습니다. 다음은 관련 부분입니다 screen.c.

1561 if (WIFSTOPPED(wstat))
1562   {   
1563     debug3("Window %d pid %d: WIFSTOPPED (sig %d)\n", p->w_number, p->w_pid, WSTOPSIG(wstat));
....
1578     /* Try to restart process */
1579     Msg(0, "Child has been stopped, restarting.");
1580     if (killpg(p->w_pid, SIGCONT))
1581       kill(p->w_pid, SIGCONT);
1582   }   

이 동작은 옵션이나 구성 파일을 통해 변경할 수 없는 것 같습니다. 화면 프로세스를 중지하기 위해 제안된 솔루션에는 바람직하지 않은 부작용이 있을 수 있습니다. 더 나은 접근 방식은 중지된 프로세스를 화면에서 숨기는 것입니다. Bash 스크립트의 경우 서브셸을 사용하여 이 작업을 수행할 수 있습니다.

#!/bin/bash
(   
OFILE='log'
echo 'ok' > ${OFILE}
kill -SIGSTOP ${BASHPID}
echo 'after stop' > ${OFILE}
)   

다른 쉘의 경우에는 그렇게 간단하지 않을 수 있습니다(예: tcsh의 경우).

#!/bin/tcsh
(\  
set OFILE='log' ;\
echo 'ok' > ${OFILE} ;\
kill -STOP `exec sh -c 'echo ${PPID}'` ;\
echo 'after stop' > ${OFILE} \
)   

주요 차이점은 서브쉘의 PID를 얻는 방법입니다. 추가 정보여기.

또는 다음을 사용하여 수정하지 않고 스크립트를 시작할 수 있습니다.싸개스크립트:

#!/bin/bash
SCRIPTDIR="$(dirname "$(readlink -f -n "$0")")"
${SCRIPTDIR}/test.sh

실행하려면:

screen -d -m ./wrapper.sh

관련 정보