Envoyer la commande à l'écran détaché et obtenir la sortie

12

J'ai cherché un moyen d'envoyer une commande à une session d'écran détachée. Jusqu'ici tout va bien. Voici ce que j'ai trouvé:

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

Cette commande fonctionne comme il se doit. Mais, j'aimerais aussi la sortie de celle-ci, en écho directement devant mes yeux (pas besoin d'un .logfichier ou quelque chose, je veux juste la sortie).

L'utilisation de la screen -Lcommande n'est pas une option.

Robin
la source
Pourquoi faut-il que ce soit screen? N'est-ce pas pour cela que les processus enfants sont faits?
Anko

Réponses:

10

Utilisez un tuyau premier entré, premier sorti:

mkfifo /tmp/test

Utilisez un opérateur de redirection. Redirigez la sortie de la commande vers / tmp / test, par exemple comme ceci:

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

Puis dans une autre coquille

tail -f /tmp/test.

Notez que vous pouvez également rediriger les messages d'erreur à l'aide de l' opérateur 2> & 1 .

Exemple

Comme demandé dans les commentaires, supposons que nous avons un script php acceptant les entrées utilisateur et imprimant la charge du serveur sur l'entrée "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);
?>

Vous créez deux fifos:

 # mkfifo /tmp/fifoin /tmp/fifoout

Vous appelez un écran:

screen

Dans une autre console, appelons-la console 2, vous découvrirez le nom de votre écran:

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

Dans la console 2, vous envoyez la commande à l'écran:

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

vous voyez la commande apparaître à l'écran. Maintenant, dans la console 2, vous pouvez envoyer des commandes à votre processus php:

echo "status" >/tmp/fifoin

et en lire:

# cat /tmp/fifoout
load is stub
Thorsten Staerk
la source
1
Désolé, mais cela ne fonctionne pas. Si j'envoie une commande à l'écran comme «commande> / tmp / test», le processus doit prendre en charge la syntaxe> / tmp / test ... Et ce n'est pas le cas.
Robin
Pour moi cela fonctionne, veuillez noter que j'ai mis "test" comme nom d'écran. Vous pouvez trouver le nom de votre écran avec la commande screen -ls. De plus, "commande" doit être remplacée par votre commande réelle, j'ai testé avec la commande ls. Aussi, j'ai testé avec le shell bash.
Thorsten Staerk
Je le sais. Et ça ne marche pas. Par exemple, lancez un script PHP dans une fenêtre d'écran, qui, par exemple, répond à une commande "status", qui retourne la charge actuelle du serveur par exemple. Voilà ce que j'essaie de faire.
Robin
alors vous aurez besoin de tuyaux bidirectionnels,
j'ajoute
6

J'ai un script python qui garde la trace de nombreuses sessions d'écran détachées et capture la sortie de chacune (lorsque les commandes d'utilisation comme free, top -bn2, iostat sont périodiquement envoyées via «stuff»).

Au lieu de rediriger vers un fichier et, par conséquent, de gérer au moins un fichier par session d'écran détachée ... Je redirige simplement vers ce que tty / pts ma session parent utilise.

Étape # 1: Démarrez une nouvelle session d'écran (avec un nom lisible par l'homme) en mode détaché.

$ screen -dmS chad 

Étape # 2: Envoyez vos commandes (j'utiliserai la commande 'free -g' avec 'uname -r') via stuff. Il est important de spécifier la fenêtre que vous souhaitez utiliser (dans notre cas, la première et la seule fenêtre) avec -p.

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

Étape # 3: l' étape ci-dessus envoie uniquement le texte de la commande. Nous devons également envoyer un retour chariot à cette session d'écran détachée pour que le shell exécute notre commande. Le caractère ASCII 015 est un retour chariot sur la plupart des systèmes * nix.

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

Étape # 4: Redirigez la sortie de notre session d'écran détachée vers notre tty / pts actuel:

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

La sortie de l'étape # 4 ressemblera à ceci:

$ 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

Bien que cela semble un peu impliqué, le processus est facilement scriptable. Avec python, je peux analyser la sortie de l'étape # 4 et capturer uniquement les données qui m'intéressent.

En choisissant un scénario simple comme récupérer les détails IP, j'ai écrit un exemple de script pour illustrer les concepts ci-dessus. N'hésitez pas à remplacer et à bricoler comme bon vous semble.

Exemple de script python pour obtenir les détails IP d'une session d'écran détachée:

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

Script ci-dessus en action:

$ python screen-output-test.py 
      inet addr:192.168.1.201  Bcast:192.168.1.255  Mask:255.255.255.0
chad_walker
la source
J'aime cette réponse beaucoup mieux que celle acceptée, car elle ne dépend pas de l'état de l'écran "shell prompt", mais fonctionne aussi avec tout ce qui fonctionne dans cet écran.
Guntram Blohm soutient Monica le
Cependant, il nécessite que la sortie soit adaptée à l'écran. J'ai trouvé screen -X logfile /tmp/something; screen -X log on; screen -X stuff "command param"; screen -X log offpour fonctionner encore mieux dans ce scénario.
Guntram Blohm prend en charge Monica le
-1
screen -S myscreen

screen -R myscreen -X exec command

Exemple:

screen -R myscreen -X exec top
aod
la source