Envie o comando para a tela desanexada e obtenha a saída

10

Estou procurando uma maneira de enviar um comando para uma sessão de tela desanexada. Por enquanto, tudo bem. É isso que eu fiz:

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

Este comando funciona como deveria. Mas, eu também gostaria da saída, ecoada diretamente na frente dos meus olhos (não há necessidade de um arquivo .log ou algo assim, eu só quero a saída).

Usar o comando screen -L não é uma opção.

    
por Robin 19.01.2014 / 22:14

3 respostas

8

Use o primeiro no primeiro canal:

mkfifo /tmp/test

Use um operador de redirecionamento. Saída do comando de redirecionamento para / tmp / test, por exemplo, assim:

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

Então, em outro shell

tail -f /tmp/test.

Observe que você também pode redirecionar as mensagens de erro usando a operadora 2 > & 1 .

Exemplo

Conforme solicitado nos comentários, vamos supor que temos um script php aceitando a entrada do usuário e imprimindo a carga do servidor na entrada de "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);
?>

Você cria dois fifos:

 # mkfifo /tmp/fifoin /tmp/fifoout

Você chama uma tela:

screen

Em outro console, vamos chamá-lo de console 2, você descobre o nome da sua tela:

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

No console 2, você envia o comando para a tela:

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

você vê o comando que aparece na tela. Agora no console 2 você pode enviar comandos para o seu processo de php:

echo "status" >/tmp/fifoin

e leia a partir dele:

# cat /tmp/fifoout
load is stub
    
por 21.01.2014 / 10:55
4

Eu tenho um script python que controla várias sessões de tela desanexadas e captura as saídas de cada uma delas (quando comandos de utilização como free, top -bn2, iostat são periodicamente enviados via 'stuff'). / p>

Em vez de redirecionar para um arquivo e, assim, gerenciar pelo menos um arquivo por sessão de tela desanexada ... eu simplesmente redireciono para qualquer tty / pts que minha sessão pai esteja usando.

Etapa 1: Inicie uma nova sessão de tela (com um nome legível por humanos) no modo desanexado.

$ screen -dmS chad 

Passo # 2: Envie seus comandos (eu usarei o comando 'free -g' junto com 'uname -r') via coisas. É importante especificar a janela que você deseja usar (no nosso caso, a primeira e única janela) com -p.

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

Passo # 3: O passo acima apenas envia o texto de comando. Precisamos também enviar um retorno de carro para esta sessão de tela desanexada para que o shell execute nosso comando. O caractere ASCII 015 é um retorno de carro na maioria dos sistemas * nix.

$ screen -r chad -p0 -X eval "stuff 5"

Passo # 4: Redirecionar a saída da nossa sessão de tela desanexada para o nosso atual tty / pts:

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

A saída da Etapa 4 será parecida com esta:

$ 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

Embora isso pareça um pouco envolvido, o processo é facilmente programável. Com o python, posso analisar a saída da Etapa 4 e capturar somente os dados que me interessam.

Escolhendo um cenário simples como pegar detalhes de IP, escrevi um script de exemplo para demonstrar os conceitos acima. Sinta-se à vontade para substituir e mexer como quiser.

Exemplo de script python para obter detalhes de IP de uma sessão de tela desanexada:

#!/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()

Acima do script em ação:

$ python screen-output-test.py 
      inet addr:192.168.1.201  Bcast:192.168.1.255  Mask:255.255.255.0
    
por 15.04.2015 / 01:53
-1
screen -S myscreen

screen -R myscreen -X exec command

Exemplo:

screen -R myscreen -X exec top
    
por 28.11.2014 / 19:56