Exécuter l'écran (GNU) à partir du script

11

Je voudrais lancer une application à l'intérieur d'une session écran mais à partir d'un script.
Sans script, je lancerais simplement l'écran, puis ouvrirais N fenêtres avec crtl-ac et exécuterais des programmes dans chaque fenêtre.

J'ai essayé ce qui suit

screen -d -m -S test
screen -S test -X exec tail -f /var/log/messages
screen -S test -X screen
screen -S test -X exec tail -f /var/log/xinetd.log

Mais quand j'attache la queue de session ne fonctionne pas. Si j'attache la session juste après screen -d -m -S startupet que je l' exécute à screen -S startup -X exec tail -f /var/log/messagespartir d'un autre terminal, cela fonctionne.

Ai-je oublié quelque chose ?

Modifier après la réponse d'AlexD:

Une solution à moitié fonctionnelle est

screen -d -m -S test tail -f /var/log/messages
screen -S test -X screen tail -f /var/log/xinetd.log

Le chaînage de la commande d'écran (celle après -X) avec la commande fonctionne alors que exec n'est probablement pas parce que exec attend une fenêtre actuelle à définir alors qu'il n'y en a pas une lorsque l'écran est détaché. Merci à AlexD pour ces conseils.

Mais il y a un effet secondaire étrange: lorsque le programme s'arrête (si vous attachez la session d'écran et crtl-c la queue, ou tuez la queue), la fenêtre d'écran se fermera.
Donc, le comportement n'est pas le même que Crtl-A c et exécutez la commande
Un autre effet secondaire est que vous ne pouvez pas enchaîner 2 commandes

rayon
la source
screen se termine toujours lorsque la commande qui a été lancée se termine - c'est une fonctionnalité normale de l'outil :) .. donc si vous exécutez screen top, lorsque vous quittez top, se screenfermera aussi
warren
Oui je le sais maintenant, c'est pourquoi j'ai essayé de lancer screen en tant que démon puis d'utiliser exec puis d'utiliser la commande screen pour ouvrir une nouvelle fenêtre (lancement d'un shell). J'ai aussi essayé tu prepend bash entre exec et tail ou entre screen et tell mais aucun ne fonctionne
radius

Réponses:

14

La screen -S test -X screen commandcommande est ce dont vous avez besoin pour ajouter des fenêtres à votre session démon, mais pas pour les raisons que vous donnez. Cela fonctionne parce que -X prend une commande d'écran et non une commande shell, et la commande d'écran pour créer une fenêtre s'appelle, confusément, écran. Il n'y a pas de commande d'écran exec. Il n'y a pas de chaînage non plus, sauf si vous créez votre commande à l'aide de scripts shell (comme ceci:) screen -S script -X screen sh -c 'command1; command2;'.

Appeler screen -S test -X screensans commande est inutile car la commande par défaut est un shell, et une fois que vous avez généré un shell, vous n'avez pas de moyen non interactif (et non sournois) d'exécuter des commandes à l'intérieur de ce shell. Il est préférable d'exécuter la commande seule, sans shell interactif. Un effet secondaire est que lorsque la commande se termine, la fenêtre d'écran n'a plus d'enfant et se ferme.

Maintenant, vous pouvez demander à screen de maintenir la fenêtre ouverte de toute façon, une fois la commande terminée. Utilisez la zombiecommande d'écran pour l'activer. Votre séquence ressemble à:

screen -d -m -S script
screen -S script -X zombie qr
screen -S script -X screen tail -f /var/log/messages
screen -S script -X screen tail -f /var/log/xinetd.log

Pour rattacher de manière interactive:

screen -S script -r

Et enfin, vous pouvez réécrire ces commandes -X en tant que script screenrc à la place.

Screenrc:

zombie qr
screen tail -f /var/log/messages
screen tail -f /var/log/xinetd.log

Scénario:

screen -d -m -S script -c screenrc
Tobu
la source
Oui, je sais que -X prend une commande d'écran, c'est ce que je veux dire quand j'ai dit "Chaîne de commande d'écran (celle après -X)" (Ok ce n'est pas clair du tout) mais il y a une commande d'écran exec, regardez l'homme page, mais comme vous l'avez dit, il n'y a aucun moyen de le faire fonctionner comme souhaité en mode non interactif. Quoi qu'il en soit, avec la solution AlexD et votre commande zombie, j'ai obtenu ce que je veux! Merci
rayon
@Tobu: +200 pour avoir mentionné les zombies! Je ne l'aurais finalement jamais remarqué dans cet horrible manuel!
vignes du
6

Si vous voulez le même effet que Ctrl-A cvous devez utiliser à la screenplace de exec:

screen -S test -X screen tail -f / var / log / messages
écran -S test -X écran
screen -S test -X screen tail -f /var/log/xinetd.log

En outre, vous pouvez déplacer vos commandes ci-dessus dans un $HOME/.screenrc-younameitfichier (sans screen -S test -Xpréfixe) et lancer screen -c $HOME/.screenrc-younameitlorsque vous souhaitez créer une session d'écran spécifique.

AlexD
la source
Le Ctrl-A c est dans ma 3ème ligne, je suppose que exec ne fonctionne pas car exec exécute la commande dans les fenêtres actuelles qui pourraient ne pas être définies lorsque l'écran est détaché. Votre écran de chaînage de contournement et la commande est sympa, j'aurais dû l'essayer! Je vais ajouter une réponse pour moi parce que votre réponse n'a pas la création de session et a une ligne inutile (2ème, saut de 1 fenêtre)
rayon
En fait ça ne fonctionne pas comme prévu, les fenêtres se ferment dès l'arrêt du programme. si vous faites écran -S test -X écran ls, la fenêtre se fermera et vous ne verrez jamais le résultat
rayon
1

l'utilisation de byobu est- elle une option?

Sirex
la source
Je viens de l'essayer, je ne vois pas comment cela pourrait aider mais si vous avez une solution de travail avec byobu ça pourrait être ok, je préfère plutôt une solution écran uniquement mais utiliser un add-on est mieux que de ne pas avoir de solution!
rayon
1

Je faisais la même chose ce soir, je voulais ouvrir l'écran avec plusieurs fichiers pré-ouverts. Il m'a fallu un certain temps pour comprendre tout cela, mais j'ai finalement trouvé ce qui suit qui semble fonctionner assez bien:


#1/bin/sh 
screen -d -m -S CS140 
screen -S CS140 -X screen -t thread.c 
screen -p 1 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.c\015"'
screen -S CS140 -X screen -t thread.h 
screen -p 2 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.h\015"'
screen -S CS140 -X screen -t palloc.c 
screen -p 3 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/palloc.c\015"'
screen -S CS140 -X screen -t intr-stubs.h 
screen -p 4 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/intr-stubs.h\015"'
screen -S CS140 -X screen -t pagedir.c 
screen -p 5 -S CS140 -X eval 'stuff "vim cs140-ps2/src/userprog/pagedir.c\015"'
screen -r -d CS140 

Cela créera six écrans différents, les écrans 1 à 5 ayant ouvert divers fichiers. Je ne connais pas tous les détails, mais «stuff» dit essentiellement à l'écran que le texte cité ci-dessous n'est pas une commande d'écran. L'évalu évloute alors tout ce qui est contenu dans les devis. Sans cela, screen -p 4 -S CS140 -X stuff "vim cs140-ps2/src/threads/intr-stubs.h\015" il canalise simplement le texte cité sans l'exécuter. Eval lira '\ 015' comme une nouvelle ligne et exécutera ainsi le texte précédent.

En termes d'autres détails, screen -p 1 -S CS140 -X CMD indique au shell d'envoyer le «CMD» à la première fenêtre de la session d'écran nommée «CS140».

J'espère que cela pourra aider!

DevonH
la source