Run (GNU) Экран из скрипта

11

Я хотел бы запустить некоторое приложение в сеансе экрана, но из сценария.
Без скрипта я бы просто запускал экран, затем открывал N окон с помощью crtl-ac и запускал программы в каждом из них.

Я попробовал следующее

screen -d -m -S test
screen -S test -X exec tail -f /var/log/messages
screen -S test -X screen
screen -S test -X exec tail -f /var/log/xinetd.log

Но когда я прикрепляю сессию, хвост не работает. Если я присоединяю сеанс сразу после этого screen -d -m -S startupи запускаю screen -S startup -X exec tail -f /var/log/messagesиз другого терминала, он работает.

Я что-то пропустил ?

Изменить после ответа AlexD:

Половинное рабочее решение

screen -d -m -S test tail -f /var/log/messages
screen -S test -X screen tail -f /var/log/xinetd.log

Цепная команда экрана (та, что после -X) с командой работает, в то время как exec, вероятно, не работает, потому что exec ожидает, что текущее окно будет определено, в то время как нет текущего, когда экран отключен. Спасибо AlexD за эти советы.

Но есть странный побочный эффект: когда программа останавливается (если вы присоединяете сеанс экрана и crtl-c хвост или убивает хвост), окно экрана закрывается.
Таким образом, поведение не совпадает с Crtl-A c и запустите команду.
Другой побочный эффект заключается в том, что вы не можете соединить 2 команды

радиус
источник
screen всегда завершается, когда запускается команда, с которой он был запущен - это обычная особенность инструмента :) .. так что если вы запускаете screen top, когда вы выходите top, screenтоже завершается
warren
Да, теперь, вот почему я попытался запустить screen как deamon, затем использовать exec, а затем использовать команду screen, чтобы открыть новое окно (запуск оболочки). Я также попытался сделать предварительный удар между exec и tail или между экраном и сказать, но ни один из них не работает
радиус

Ответы:

14

Команда screen -S test -X screen command- это то, что вам нужно, чтобы добавить окна в сеанс демона, но не по указанным вами причинам. Это работает, потому что -X принимает команду экрана, а не команду оболочки, и команда экрана для создания окна вызывается, до смешного, экраном. Нет экранной команды exec. Также нет никакой цепочки, если вы не строите свою команду, используя сценарии оболочки (как это :) screen -S script -X screen sh -c 'command1; command2;'.

Вызов screen -S test -X screenбез команды бесполезен, потому что команда по умолчанию - это оболочка, и как только вы породили оболочку, у вас не будет неинтерактивного (и не хитрого) способа запуска команд внутри этой оболочки. Команду лучше запускать отдельно, без интерактивной оболочки. Побочным эффектом является то, что когда команда завершается, окно экрана больше не имеет дочернего элемента и закрывается.

Теперь вы можете попросить экран держать окно открытым в любом случае после завершения команды. Используйте zombieэкранную команду, чтобы включить это. Ваша последовательность выглядит так:

screen -d -m -S script
screen -S script -X zombie qr
screen -S script -X screen tail -f /var/log/messages
screen -S script -X screen tail -f /var/log/xinetd.log

Для подключения в интерактивном режиме:

screen -S script -r

И, наконец, вы можете переписать эти команды -X вместо сценария screenrc.

Screenrc:

zombie qr
screen tail -f /var/log/messages
screen tail -f /var/log/xinetd.log

Автор сценария:

screen -d -m -S script -c screenrc
Tobu
источник
Да, я знаю, что -X принимает экранную команду, что я имею в виду, когда говорю «Цепная экранная команда (та, что после -X)» (Хорошо, это не совсем понятно), но есть команда exec для экрана, посмотрите на человека страницы, но, как вы сказали, нет способа заставить его работать так, как хотелось бы в неинтерактивном режиме. Во всяком случае, с решением AlexD и добавлением команды зомби, я получил то, что хочу! Спасибо
радиус
@Tobu: +200 за упоминание зомби! В конечном счете, я бы никогда не заметил этого в этом ужасном руководстве!
лозы
6

Если вы хотите такой же эффект, как Ctrl-A cтогда, вы должны использовать screenвместо exec:

экран -S тест -X экран хвост -f / var / log / messages
экран -S тест -X экран
экран -S тест -X экран хвост -f /var/log/xinetd.log

Кроме того, вы можете переместить свои команды выше в $HOME/.screenrc-younameitфайл (без screen -S test -Xпрефикса) и запустить, screen -c $HOME/.screenrc-younameitкогда вы хотите создать определенный сеанс экрана.

AlexD
источник
Ctrl-A c находится в моей 3-й строке, я полагаю, что exec не работает, потому что exec запускает команду в текущих окнах, которая может не быть определена при отключении экрана. Ваш обходной экран и команда хороши, я должен был попробовать! Я добавлю ответ самому себе, потому что в вашем ответе отсутствует создание сеанса и есть бесполезная строка (2-й, пропускается 1 окно)
радиус
На самом деле это не работает, как ожидалось, окна закрываются, как только программа останавливается. если вы выполните экран -S test -X screen ls, окно закроется, и вы никогда не увидите результат
радиус
1

использует byobu вариант?

Sirex
источник
Я только что попробовал, я не вижу, как это могло бы помочь, но если у вас есть работающее решение с byobu, это может быть хорошо, я предпочитаю решение только для экрана, но использование дополнения лучше, чем отсутствие решения!
радиус
1

Я делал то же самое сегодня вечером, я хотел открыть экран с несколькими предварительно открытыми файлами. Мне потребовалось некоторое время, чтобы понять все это, но я наконец-то нашел следующее, которое, кажется, работает довольно хорошо:


#1/bin/sh 
screen -d -m -S CS140 
screen -S CS140 -X screen -t thread.c 
screen -p 1 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.c\015"'
screen -S CS140 -X screen -t thread.h 
screen -p 2 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.h\015"'
screen -S CS140 -X screen -t palloc.c 
screen -p 3 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/palloc.c\015"'
screen -S CS140 -X screen -t intr-stubs.h 
screen -p 4 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/intr-stubs.h\015"'
screen -S CS140 -X screen -t pagedir.c 
screen -p 5 -S CS140 -X eval 'stuff "vim cs140-ps2/src/userprog/pagedir.c\015"'
screen -r -d CS140 

Это создаст шесть разных экранов, с экранами 1-5, на которых открыты различные файлы. Я не знаю всех особенностей, но «вещи», по сути, говорят экрану, что следующий цитируемый текст не является командой экрана. Затем «eval» уничтожает все, что содержится в кавычках. Без этого screen -p 4 -S CS140 -X stuff "vim cs140-ps2/src/threads/intr-stubs.h\015" просто передает цитируемый текст, не выполняя его. Eval будет читать '\ 015' как новую строку и, таким образом, исполнять предыдущий текст.

Что касается других деталей, screen -p 1 -S CS140 -X CMD говорит оболочке отправить «CMD» в первое окно сеанса экрана с именем «CS140».

Надеюсь, это поможет!

DevonH
источник