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

Ядро 2.6.32 с 2009; Вы не можете ожидать что старые драйверы работать с новым оборудованием.

Попытайтесь получить более новое ядро CrunchBang или переключиться на другое распределение.

12
20.01.2014, 00:55
3 ответа

Используйте канал метода "первым пришел - первым вышел":

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);
?>

Вы создаете два fifos:

 # 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
10
27.01.2020, 19:55
  • 1
    Извините, но это не работает. Если я отправляю, команда к creen как 'команда>/tmp/test' процесс должна поддерживать>/tmp/test синтаксис... И это не делает. –  Robin 31.01.2014, 20:46
  • 2
    Для меня это работает, обратите внимание на то, что я поместил "тест" как имя Вашего экрана. Можно узнать, что имя экрана с командой экранирует-ls. Кроме того, "команда" должна быть заменена Вашей фактической командой, я протестировал с командой ls. Кроме того, я протестировал с оболочкой удара. –  Thorsten Staerk 31.01.2014, 21:20
  • 3
    я знаю это. И это не работает. Например, запустите Сценарий PHP в экранном окне, которое, например, отвечает на команду "состояние", которое возвращает текущую загрузку сервера, например. Это - то, что я пытаюсь сделать. –  Robin 01.02.2014, 20:27
  • 4
    затем, Вам будут нужны двунаправленные каналы, я добавляю это к своему ответу –  Thorsten Staerk 01.02.2014, 22:14
screen -S myscreen

screen -R myscreen -X exec command

Пример:

screen -R myscreen -X exec top
-1
27.01.2020, 19:55

У меня есть питоновый скрипт, который отслеживает многочисленные сеансы работы с экраном и захватывает выходные данные с каждого из них (когда команды использования типа бесплатные, 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 я могу разобрать вывод Step #4 и захватить только те данные, которые мне небезразличны.

Выбирая простой сценарий, например, захват IP-данных, я написал пример скрипта, чтобы продемонстрировать вышеперечисленные понятия. Не стесняйтесь заменять и подправлять, как считаете нужным.

Пример питоновского сценария, чтобы получить 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
6
27.01.2020, 19:55

Теги

Похожие вопросы