Надіслати команду на відокремлений екран і отримати вихід


12

Я шукав, щоб знайти спосіб відправити команду на сеанс окремого екрана. Все йде нормально. Ось що я придумав:

$ screen -S test -p 0 -X stuff 'command\n'

Ця команда працює як слід. Але я також хотів, щоб вихід з нього теж відлунив прямо перед моїми очима (немає необхідності у .logфайлі чи чомусь, я просто хочу вихід).

Використання screen -Lкоманди - це не варіант.


Чому це має бути screen? Чи не для цього створені дитячі процеси?
Анко

Відповіді:


10

Використовуйте першу в першу трубу:

mkfifo /tmp/test

Використовуйте оператор переадресації. Наприклад, команда перенаправлення на / tmp / test, наприклад:

screen -S test -p 0 -X stuff 'command >/tmp/test\n'

Потім в іншій оболонці

tail -f /tmp/test.

Зауважте, ви також можете переспрямувати повідомлення про помилки за допомогою оператора 2> & 1 .

Приклад

Як вимагається в коментарях, припустимо, у нас є скрипт php, який приймає введення користувача та друкує завантаження сервера на вході "статусу":

# cat test.php
<?php
  $fp=fopen("php://stdin","r");
  while($line=stream_get_line($fp,65535,"\n")) 
  {
    if ($line=="status") {echo "load is stub";} 
  } 
  fclose($fp);
?>

Ви створюєте два фіфоси:

 # mkfifo /tmp/fifoin /tmp/fifoout

Ви викликаєте екран:

screen

В іншій консолі, назвемо її консоллю 2, ви дізнаєтесь назву екрана:

# screen -ls
There is a screen on:
        8023.pts-3.tweedleburg  (Attached)
1 Socket in /var/run/screens/S-root.

У консолі 2 ви відправляєте команду на екран:

 # screen -S 8023.pts-3.tweedleburg -p 0 -X stuff 'php test.php </tmp/fifoin >/tmp/fifoout\n'

ви бачите команду, що з’являється на екрані. Тепер у консолі 2 ви можете відправляти команди у ваш процес php:

echo "status" >/tmp/fifoin

і читайте з нього:

# cat /tmp/fifoout
load is stub

1
Вибачте, але це не працює. Якщо я надсилаю команду на екран на зразок "команда> / tmp / test", процес повинен підтримувати синтаксис> / tmp / test ... І це не так.
Робін

Для мене це працює, зауважте, що я поставив "тест" як ім'я вашого екрана. Дізнатися ім’я екрана можна за допомогою командного екрана -ls. Також "команду" слід замінити вашою фактичною командою, я перевірив командою ls. Також я протестував із шкаралупою bash.
Торстен Стаерк

Я знаю це. І це не працює. Наприклад, запустіть скрипт PHP у вікні екрана, який, наприклад, відповідає команді "статус", яка, наприклад, повертає поточне завантаження сервера. Це те, що я намагаюся зробити.
Робін

тоді вам знадобляться двонаправлені труби, я додаю це до своєї відповіді
Thorsten Staerk

6

У мене є сценарій python, який відслідковує численні окремі сеанси екрану та фіксує вихід з кожного (коли команди використання, такі як free, top -bn2, iostat періодично надсилаються через 'stuff').

Замість того, щоб перенаправляти на файл і, таким чином, керувати принаймні одним файлом на окремому сеансі екрана ... Я просто переспрямовую на будь-який tty / pts, який використовує мій батьківський сеанс.

Крок №1: Почніть новий сеанс на екрані (з людським читальним іменем) у відірваному режимі.

$ screen -dmS chad 

Крок №2: Надішліть свої команди (я буду використовувати команду 'free -g' разом із 'uname -r') через речі. Важливо вказати вікно, яке ви хочете використовувати (в нашому випадку перше і єдине вікно) за допомогою -p.

$ screen -r chad -p0 -X stuff "free -g; uname -r" 

Крок №3: Наведений вище крок лише надсилає текст команди. Нам також потрібно надіслати повернення каретки до цього сеансу окремого екрана, щоб оболонка виконувала нашу команду. Символ 015 ASCII - це повернення каретки для більшості * nix систем.

$ screen -r chad -p0 -X eval "stuff \015"

Крок №4: Перенаправляємо вихід нашого сеансу окремого екрана на поточний tty / pts:

$ screen -r chad -p0 -X hardcopy $(tty)

Висновок кроку №4 буде виглядати приблизно так:

$ free -g; uname -r
             total       used       free     shared    buffers     cached
Mem:             7          1          6          0          0          0
-/+ buffers/cache:          0          7
Swap:            1          0          1
2.6.32-358.el6.x86_64

Хоча це здається дещо задіяним, процес легко прописаний. За допомогою python я можу проаналізувати результат кроку №4 та захопити лише ті дані, які мене цікавлять.

Вибираючи простий сценарій, як захоплення деталей IP-адреси, я написав приклад сценарію, щоб продемонструвати вищезгадані концепції. Не соромтеся замінювати та балакати, як вважаєте за потрібне.

Приклад сценарію python для отримання деталей IP-адреси з сеансу окремого екрана:

#!/usr/bin/python

import pexpect, time

#spawn a new bash session
session = pexpect.spawn('/bin/bash')
#send screen commands
session.sendline('screen -dmS netIP')
session.sendline('screen -r netIP -p0 -X stuff "ifconfig eth0 | grep -v eth0 | head -1"')
session.sendline('screen -r netIP -p0 -X eval "stuff \\015"')
#give the command a chance to execute before reading the output of our detached screen
time.sleep(0.1)

#use the output of the uname command as our string to expect
session.sendline('screen -r netIP -p0 -X hardcopy $(tty); $(uname)')
session.expect('Linux')

#parse the output - only concerned with the 'inet' line
output = session.before.split('\n')
for o in output:
    if 'inet' in o:
        print o

#kill the screen
session.sendline('screen -r netIP -p0 -X quit')
time.sleep(0.1)

session.close()

Вище написаний сценарій:

$ python screen-output-test.py 
      inet addr:192.168.1.201  Bcast:192.168.1.255  Mask:255.255.255.0

Мені подобається ця відповідь набагато краще, ніж прийнята, тому що вона не покладається на те, що екран знаходиться в стані "швидкого оболонки", але працює і з тим, що працює на цьому екрані.
Гунтрам Блом підтримує Моніку

Тим не менш, він вимагає виводу, щоб поміститися на екрані. Я знайшов screen -X logfile /tmp/something; screen -X log on; screen -X stuff "command param"; screen -X log offпрацювати ще краще за таким сценарієм.
Гунтрам Блом підтримує Моніку

-1
screen -S myscreen

screen -R myscreen -X exec command

Приклад:

screen -R myscreen -X exec top
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.