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 신호 보내기).

테스트 파일

#!/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

관련 정보