Invia il comando allo schermo staccato e ottieni l'output


12

Ho cercato di trovare un modo per inviare un comando a una sessione schermo distaccata. Fin qui tutto bene. Questo è quello che ho escogitato:

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

Questo comando funziona come dovrebbe. Ma vorrei anche l'output da esso, echeggiato direttamente davanti ai miei occhi (non c'è bisogno di un .logfile o qualcosa del genere, voglio solo l'output).

L'uso del screen -Lcomando non è un'opzione.


Perché deve essere screen? Non è per questo che sono fatti i processi figlio?
Anko,

Risposte:


10

Utilizzare un primo nel primo tubo di uscita:

mkfifo /tmp/test

Utilizzare un operatore di reindirizzamento. Reindirizzare l'output del comando su / tmp / test ad esempio in questo modo:

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

Quindi in un altro guscio

tail -f /tmp/test.

Nota che potresti voler reindirizzare i messaggi di errore usando l' operatore 2> & 1 .

Esempio

Come richiesto nei commenti, supponiamo di avere uno script php che accetta l'input dell'utente e stampa il carico del server sull'input di "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);
?>

Si creano due quindici:

 # mkfifo /tmp/fifoin /tmp/fifoout

Si chiama uno schermo:

screen

In un'altra console, chiamiamola console 2 scopri il nome del tuo schermo:

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

Nella console 2 si invia il comando allo schermo:

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

vedi il comando che appare sullo schermo. Ora nella console 2 puoi inviare comandi al tuo processo php:

echo "status" >/tmp/fifoin

e leggi da esso:

# cat /tmp/fifoout
load is stub

1
Siamo spiacenti, ma questo non funziona. Se sto inviando un comando alla schermata come 'command> / tmp / test' il processo deve supportare la sintassi> / tmp / test ... E non lo fa.
Robin,

Per me funziona, tieni presente che ho messo "test" come nome del tuo schermo. Puoi scoprire il nome dello schermo con il comando screen -ls. Inoltre, "comando" dovrebbe essere sostituito dal tuo comando effettivo, ho provato con il comando ls. Inoltre, ho provato con la shell bash.
Thorsten Staerk,

Lo so. E non funziona. Ad esempio, avviare uno script PHP in una finestra dello schermo, che, ad esempio, risponde a un comando "status", che restituisce ad esempio il carico del server corrente. Questo è quello che sto cercando di fare.
Robin,

allora avrai bisogno di tubi bidirezionali, sto aggiungendo questo alla mia risposta
Thorsten Staerk

6

Ho uno script Python che tiene traccia di numerose sessioni a schermo staccato e cattura l'output di ciascuna (quando i comandi di utilizzo come free, top -bn2, iostat vengono periodicamente inviati tramite 'roba').

Invece di reindirizzare a un file e, quindi, gestire almeno un file per sessione schermo distaccata ... Devo semplicemente reindirizzare a qualunque tty / pts la mia sessione padre stia usando.

Passaggio n. 1: avvia una nuova sessione schermo (con un nome leggibile) in modalità staccata.

$ screen -dmS chad 

Step # 2: Invia i tuoi comandi (userò il comando 'free -g' insieme a 'uname -r') tramite roba. È importante specificare la finestra che si desidera utilizzare (nel nostro caso, la prima e unica finestra) con -p.

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

Passaggio n. 3: il passaggio precedente invia solo il testo del comando. Dobbiamo anche inviare un ritorno a capo a questa sessione schermo distaccato per fare in modo che la shell esegua il nostro comando. Il carattere ASCII 015 è un ritorno a capo sulla maggior parte dei sistemi * nix.

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

Passaggio n. 4: reindirizzare l'output della nostra sessione di schermo staccato ai nostri tty / pts attuali:

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

L'output del passaggio n. 4 avrà un aspetto simile al seguente:

$ 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

Anche se questo sembra un po 'coinvolto, il processo è facilmente gestibile tramite script. Con Python, posso analizzare l'output del passaggio n. 4 e acquisire solo i dati che mi interessano.

Scegliendo uno scenario semplice come afferrare i dettagli IP, ho scritto uno script di esempio per dimostrare i concetti sopra. Sentiti libero di sostituire e armeggiare come meglio credi.

Esempio di script Python per ottenere i dettagli IP da una sessione schermo distaccata:

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

Sopra lo script in azione:

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

Mi piace questa risposta molto meglio di quella accettata, perché non dipende dal fatto che lo schermo sia nello stato di "prompt della shell", ma funziona anche con qualsiasi cosa sia in esecuzione in quella schermata.
Guntram Blohm supporta Monica il

Tuttavia, richiede che l'output si adatti allo schermo. Ho trovato screen -X logfile /tmp/something; screen -X log on; screen -X stuff "command param"; screen -X log offper lavorare ancora meglio in quello scenario.
Guntram Blohm supporta Monica il

-1
screen -S myscreen

screen -R myscreen -X exec command

Esempio:

screen -R myscreen -X exec top
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.