Отправить команду на отдельный экран и получить вывод


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-скрипт, принимающий вводимые пользователем данные и печатающий нагрузку на сервер при вводе «status»:

# 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

В другой консоли, назовем это console 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
Извините, но это не работает. Если я посылаю команду на экран, например 'command> / tmp / test', процесс должен поддерживать синтаксис> / tmp / test ... А это не так.
Робин

Для меня это работает, пожалуйста, обратите внимание, что я поставил «тест» в качестве имени вашего экрана. Вы можете узнать имя своего экрана с помощью командной строки -ls. Кроме того, «команда» должна быть заменена вашей действительной командой, которую я тестировал командой ls. Также я тестировал с оболочкой bash.
Торстен Стаерк

Я знаю это. И это не работает. Например, запустите PHP-скрипт в экранном окне, которое, например, отвечает на команду «status», которая, например, возвращает текущую загрузку сервера. Это то, что я пытаюсь сделать.
Робин

тогда вам понадобятся двунаправленные трубы, я добавляю это к своему ответу
Торстен Стерк

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: Приведенный выше шаг только отправляет текст команды. Нам также необходимо отправить возврат каретки в этот отдельный сеанс экрана, чтобы оболочка выполнила нашу команду. Символ ASCII 015 - это возврат каретки в большинстве систем * 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.