Предотвращение завершения экрана 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.