Предотвращение завершения экрана GNU после завершения выполненного скрипта


35

Я пытаюсь заставить экран GNU создать «виртуальный» терминал, не подключаясь к нему, выполнить сценарий внутри и НЕ завершать сеанс после завершения сценария.

Я перепробовал много комбинаций, в том числе:

screen -dmS udplistener /share/Sys/autorun/start_udp_listeners.sh

или

screen -S udplistener -X /share/Sys/autorun/start_udp_listeners.sh

и никто из них не работал. Я либо получаю сеанс без выполненного сценария, сценарий выполняется, но сеанс прекращается после его завершения, или я получаю сообщение об ошибке «Нет сеанса экрана найден»

В основном я пытаюсь запустить слушатель UDP, написанный на PHP, и заставить его работать в бесконечном цикле (не прерывать прослушивание). Да, я мог бы запустить PHP-скрипт &в конце, заставив PHP CLI работать как демон. Проблема в том, что я использую кусок мусора, называемый сервером (QNAP - никогда, никогда не покупайте этот мусор!), Который, кажется, игнорирует это. Как только я завершаю сеанс SSH, сценарии останавливаются.

Так что, screenкажется, единственный вариант. Но я не могу понять, почему он завершает сессию после завершения выполненной команды или сценария?

РЕДАКТИРОВАТЬ : Я также попробовал пример, найденный в Интернете:

screen -dmS name
screen -S name -p windowname -X stuff 'mc
'

Нет недостатка! После прикрепления к нему ( screen -R name) я вижу, что Полуночный Командир не был казнен. Хотя автор примера сказал, что так и будет.


То, как вы вызываете screen, вы только создаете одно окно для запуска одной команды. Когда команда завершается, окно закрывается и screenбольше нечего делать, поэтому оно завершается.
jw013

Итак ... есть ли способ открыть два окна (используя только командную строку, без сочетаний клавиш), одно для выполнения скрипта, а второе для предотвращения screenзакрытия? Кстати, я до сих пор не понимаю идею! Если я звоню screen -dmS name, я создаю отдельное окно, которому тоже нечего делать. Но он не закрывается автоматически! Но когда я хочу выполнить что-то на этом отдельном экране, это заканчивается, когда выполнение завершено. Зачем? Я не вижу здесь логики. Может ли окно ничего не делать, но не может, чтобы окно что-то делало, а потом ничего не делало?
Трейдер

2
Когда вы запускаете окно без указания команды, оно не «ничего не делает». Он выполняет интерактивную оболочку, которая не завершается, пока вы не закроете ее вручную.
jw013

Круто! Спасибо за объяснение! Итак ... вернемся к вопросу ... есть ли способ запустить команду внутри отдельного экрана / окна и НЕ завершить этот сеанс после завершения выполнения команды? Также, пожалуйста, посмотрите на обновленный вопрос. Спасибо.
Трейдер

Этот скрипт выполняет два прослушивателя UDP, написанных на PHP. Хотя оба они выполняются как демоны (с &в конце), из-за глючного сервера (QNAP) они завершаются по окончании сеанса (мне сказали, что они не должны работать в обычном Linux, если выполняются с &). Так что я не собираюсь ничего делать после start_udp_listeners.shфиниша, только как предотвратить прекращение сессии. Пока это не так, мои слушатели PHP работают просто отлично.
Трейдер

Ответы:


42

Чтобы экран был занят после завершения сценария, просто сохраняйте что-то постоянное в окне. Самый простой выбор для этого «чего-то» - это, вероятно, интерактивная оболочка. Вот один из способов сделать это (при условии bashвыбора интерактивной оболочки):

screen -dmS session_name sh -c '/share/Sys/autorun/start_udp_listeners.sh; exec bash'
  • -dm: запускает экран в отдельном режиме
  • -S: устанавливает имя сеанса для экрана для более удобного поиска позже
  • sh -c '...': вместо того, чтобы просто запустить скрипт, который завершится, используйте sh -cдля запуска нескольких команд
  • exec bash: после того, как скрипт завершится, shсверху переключится на интерактивную оболочку ( bash), которая никогда не завершится, пока что-то внешнее не завершит ее. Это будет оставаться screenоткрытым, пока bashэкземпляр жив.

1
Хм ... кажется, ты спаситель моей жизни! :] Расширение вашего решения export IGNOREEOF=1для предотвращения случайного завершения с помощью Ctrl + D должно дать мне идеальное решение, которое я искал целый долгий вечер. БЛАГОДАРНОСТЬ! :]
Трейдер

На сегодняшний день это не работает в Debian, -c является аргументом для чтения альтернативного файла .screenrc ...
ToVine

@ToVine отлично работает на Debian Stable (Wheezy). Я использовал, bash -cхотя.
TranslucentCloud

@TranslucentCloud Вы заключили всю команду "bash -c ..." в кавычки? В прошлый раз, когда я попробовал это (прямо перед написанием комментария), это не работало для меня, не совсем уверен, почему ...
ToVine

@ToVine вот моя команда:screen -LS sauf bash -c "sudo aptitude update && sudo aptitude full-upgrade; exec bash"
TranslucentCloud

2

Мне не повезло с sh -cмоей Raspberry Pi 2 под управлением Debian 7.8. Но bash -cсделал работу:

Команда:

/usr/bin/screen -dmS test-screen bash -c "/usr/bin/top; exec bash"

Может ли это быть, потому что вы используете (на Raspberry Pi) другую оболочку? bashИ , как shпредставляется, два различных оболочек. Это все, я думаю, но я могу ошибаться, поскольку я новичок в Linux вообще.
Трейдер

1
sh - это unix-оболочка по умолчанию, она включена в raspbian (debian). Команда sh также работает, но не sh -c в сочетании с экраном.
scotty86

Спасибо @ scotty86, я наблюдал то же самое в Linux Mint 19 (Ubuntu 18.04) и изменения sh -cк bash -cсделал трюк. Я не понимаю, почему, оба shи bashустановлены, поэтому я все еще теряю сон из-за этого, но по крайней мере это работает.
Редсандро

shвероятно указывает на /bin/dashвместо /bin/bash. Debian переключил оболочку по умолчанию bashна dashнесколько лет назад.
Scai
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.