Почему SIGSTOP не работает внутри сеанса экрана?

Рассмотрим следующий сценарий:

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

В интерактивной оболочке сценарий остановлен, и выход в ok . Однако, если он запущен как

 screen -d -m ./test.sh 

выход after stop . Отображает ли экран сигнал? Как приостановить процесс на сеансе экрана?

  • Где хранятся токены AFS и как их заставить запускать сеанс экрана
  • Экран экрана GNU переименовывается всякий раз, когда я набираю команду
  • Экран GNU не работает, если от root до обычного пользователя
  • Как возобновить несколько экземпляров экрана из командной строки с минимальными шагами?
  • Запустить скрипт на экране
  • Отправка текста из сценария на экран
  • Заголовок экранного окна возвращается после запуска команды на моей новой машине
  • `cd` все экраны для PWD текущего экрана
  • 2 Solutions collect form web for “Почему SIGSTOP не работает внутри сеанса экрана?”

    Вероятно, процесс экрана перезапускает остановленный процесс 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. 

    Изучение исходного кода GNU screen-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 
    Linux и Unix - лучшая ОС в мире.