Забороніть екрану 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, і змусити його працювати в циклі infinte (не порушувати прослуховування). Так - я міг запустити PHP-скрипт із &кінцем, змусивши PHP CLI запуститись як демон. Проблема полягає в тому, що я використовую шматок сміття під назвою сервер (QNAP - ніколи, ніколи не купуй цей мотлох!), Який, схоже, ігнорує це. Як тільки я виходжу з сеансу SSH, сценарії припиняються.

Так screenздається, єдиний варіант. Але я не можу зрозуміти, чому він припиняє сеанс, коли виконується команда чи сценарій закінчується?

EDIT : Я також спробував приклад, знайдений в Інтернеті:

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, повинно дати мені ідеальне рішення, я шукав цілий довгий вечір. СПАСИБІ! :]
trejder

На сьогоднішній день це не працює на 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моїм малиновим пі 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.