envoi de texte à un écran détaché

44

J'essaie d'exécuter un serveur Minecraft sur mon serveur unRAID.

Le serveur s'exécutera dans le shell, puis attendra une entrée. Pour l'arrêter, je dois taper 'stop' et appuyer sur entrée. Le logiciel sauvera le monde et sortira avec élégance. Je suis de retour dans le shell. Tout cela fonctionne si je le lance via Telnetting dans la boîte NAS, mais je veux le lancer directement sur la boîte.

Voici ce que j’avais eu lors d’une première tentative:

#define USER_SCRIPT_LABEL Start Minecraft server
#define USER_SCRIPT_DESCR Start minecraft server. needs sde2 mounted first
cd /mnt/disk/sde2/MCunraid
screen -d -m -S minecraft /usr/lib/java/bin/java -Xincgc -Xmx1024M -jar CraftBukkit.jar

MCunraid est le dossier où se trouvent Craftbukkit.jar et tous les fichiers du monde, etc. Si je tape directement cette ligne d'écran, la configuration de l'écran est détachée et le serveur se lance. Si j'exécute cette ligne depuis le script, il ne semble pas y avoir d'écran

pour arrêter le serveur, je dois «taper» dans STOP, puis appuyer sur Entrée. Mon approche était

screen -S minecraft -X stuff "stop $(echo -ne '\r')"

envoyer à l'écran 'minecraft' le texte et un retour chariot. Mais cela ne fonctionne pas, même si je le tape directement sur la ligne de commande. Mais si je «screen -r», je peux accéder à l'écran avec le serveur en cours d'exécution, puis taper «stop» et il s'arrête correctement.

Le serveur fonctionne bien si je me connecte par telnet et manuellement, il suffit de l’exécuter sans être connecté à partir de mon ordinateur distant.

Richard Plumb
la source
Cela semble juste . Quel est le contenu complet du script et comment l'exécutez-vous? Est-ce qu'il produit une sortie? Comment dites-vous que cela screenn'a pas commencé? Essayez d’ajouter set -xen haut du script (juste après la #!ligne) et de signaler la sortie de trace lorsque vous exécutez le script.
Gilles, arrête de faire le mal
c’est tout le contenu du script :) la commande screen fonctionne si je le tape directement, je pense donc que mon problème principal est la partie arrêt
richard plumb,
Vous avez écrit «Si j'exécute cette ligne à partir du script, elle ne semble pas créer d'écran». La partie de départ fonctionne-t-elle ou non? Si ce n'est pas le cas, consultez mon premier commentaire.
Gilles, arrête de faire le mal
J'essaie de l'exécuter en tant que script utilisateur UNMENU. Si j'ai le script utilisateur avec cette commande d'écran exacte, rien ne se passe. Si je tape la commande screen dans une fenêtre telnet, le serveur sera lancé dans un écran comme vous le souhaitiez. Donc, je pense qu'il y a une différence que je ne comprends pas dans la manière dont les scripts utilisateur unMENU sont gérés.
richard plomb
Maintenant, nous allons quelque part. Veuillez mettre à jour votre question en indiquant comment vous utilisez unMENU. Et n'essayez d' ajouter deux lignes #!/bin/bashet set -xen haut du script, et nous montrer la sortie de trace à partir du script. Vous devrez peut-être consulter la documentation unMENU pour savoir où cette sortie est envoyée.
Gilles, arrête de faire le mal

Réponses:

40

Je peux résoudre au moins une partie du problème: pourquoi la stoppartie ne fonctionne pas. Expérimentalement, lorsque vous démarrez une session Screen en mode détaché ( screen -d -m), aucune fenêtre n’est sélectionnée. Par conséquent, les entrées envoyées plus tard avec screen -X stuffsont simplement perdues. Vous devez spécifier explicitement que vous souhaitez envoyer les séquences de touches à la fenêtre 0 ( -p 0). C'est une bonne idée quand même, au cas où vous créeriez d'autres fenêtres dans cette session Screen pour quelque raison que ce soit.

screen -S minecraft -p 0 -X stuff "stop^M"

(L’écran est traduit ^Men control-M qui est le caractère envoyé par la Enterclé.)

Le problème lié au démarrage de la session à partir d'un script est probablement lié à unMENU.

Gilles, arrête de faire le mal
la source
1
beau, fonctionne très bien (du moins à partir de la ligne de commande, poussera les gars de ce menu plus tard). Cela semble avoir jeté pas mal de monde et c'est la première fois que je vois une solution concrète. J'aimerais juste avoir assez de points pour vous faire voter: D
richard à plomb
Merde s ** t! Cela fonctionne même si l'écran est déjà attaché, sans le remettre en place! C'est un excellent moyen d'envoyer des commandes à des applications simples à partir d'autres applications du système. Merci! :)
Grzegorz Wierzowiecki
Je n’ai jamais eu ce problème, probablement parce que j’ai toujours prévu d’avoir plusieurs fenêtres (nommées) dans ma session d’écran et que je choisis toujours fenêtre par nom.
Ekevoo
Manuel, à titre de référence: -X Envoie la commande spécifiée à une session d'écran en cours d'exécution. Vous pouvez utiliser l'option -S pour spécifier la session d'écran si plusieurs sessions d'écran sont en cours d'exécution. Vous pouvez utiliser l'option -d ou -r pour indiquer à l'écran de rechercher uniquement les sessions d'écran attachées ou détachées. Notez que cette commande ne fonctionne pas si la session est protégée par mot de passe.
KrisWebDev
3
ça ne marche pas pour moi. J'ai créé un écran avec screen -d -m -S hi, puis je lance screen -S hi -p 0 -X stuff "cd <some_directory>^M"et je n'obtiens rien en conséquence ... il envoie simplement "cd <répertoire_un>> M" sous forme de chaîne et n'interprète pas "^ M" en tant que clé d'entrée ...
Tanner Strunk
23

Tout d'abord, une note sur l'entrée facile des nouvelles lignes

Juste un avertissement que la $()construction supprime les nouvelles lignes de la sortie de la commande afin que les lignes de sortie puissent être utilisées comme arguments pour d'autres programmes. Cela peut provoquer un comportement inattendu. Dans ce cas, je suppose que vous essayez spécifiquement d’envoyer l’équivalent de la Enterfrappe au clavier. Bien que le retour à la ligne que vous envoyez \rne soit pas rayé, il existe plusieurs façons plus simples de saisir ce caractère sans avoir besoin de la commande supplémentaire.

  1. Vous pouvez placer une nouvelle ligne à l'intérieur de vos guillemets

    screen -S minecraft -X stuff "stop
    "
    
  2. Ou vous pouvez entrer le caractère dans une ligne de terminal en utilisant la séquence Ctrl+ v Enter. Cela ressemblera à quelque chose comme ^Mdans le terminal, mais c'est un caractère spécial de nouvelle ligne.

    screen -S minecraft -X stuff "stop^M"
    

Deuxièmement, une note sur le comportement erratique de l'écran. ( Explication et solution de Gilles )

Screen a un problème avec l'acceptation d'entrée dans une session d'écran qui n'a jamais été attachée. Si vous exécutez ceci, cela aura échoué:

screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

Mais si vous exécutez ceci cela fonctionnera:

screen -d -m -S minecraft zsh
screen -r minecraft (then disconnect with Ctrl-a-d)
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

Enfin, vous pouvez utiliser le meilleur comportement tmuxau lieu de screen.

GNU-Screen est un multiplexeur de facto depuis de nombreuses années, mais il a depuis longtemps cessé d'être développé et les bugs et les bizarreries ne sont pas corrigés. Tmux est en cours de développement, inclut de nombreuses fonctionnalités que l’écran ne peut pas toucher et son comportement immédiat est plutôt plus intuitif. En outre, c'est mieux documenté. Voici comment vous convertiriez votre code:

# Start new detached tmux session with a named window pane running the java app
tmux new-session -d -n minecraft /usr/lib/java/bin/java [args]

# Send it keys to stop the mincraft server
tmux send-keys -t minecraft "stop^M"
Caleb
la source
si je commute manuellement à l'aide de screen -r, je peux voir l'écran et aucun texte n'est entré. même si le retour de la voiture échouait, je devrais quand même me faire taper le mot 'stop'. Mais rien
richard plomba
si j'ai un script avec screen -r sur une ligne, puis screen -X "stop ^ M", le serveur est arrêté, mais se plaint également de "l'erreur d'erreur inconnue r"
richard plombé
J'ai testé ici en créant une session d'écran, puis en utilisant la commande ci-dessus et cela fonctionne parfaitement. Pouvez-vous vous connecter à votre session écran en utilisant screen -d -RR minecraft?
Caleb
oui, cela me connecte à l'écran. donc screen -r .. accroche-toi, si j'essaie screen -S minecraft -X "stop ^ M" puis screen -r, il y a du texte "stop" à l'écran.
Richard Plumb
Travaille pour moi. Peut-être avez-vous quelque chose de génial dans votre .screenrcou avez-vous un groupe de sessions d'écran défunkt ouvertes avec ce nom et envoyez-vous des données au mauvais? screen -list?
Caleb
4

Je m'excuse d'avoir découvert cet ancien message, mais cela m'aurait aidé dans mes efforts si cette information avait été disponible au moment où j'ai eu un problème similaire. Il y a beaucoup de questions sur la façon d'envoyer des commandes d'écran dans un script bash. Comme avec la peau de chat, cela peut être fait, mais j'aime bien cette façon. Avec cela, vous pouvez envoyer n'importe quelle commande ou dire n'importe quoi simplement en appelant la fonction say_this.

#!/bin/bash

say_this()
{
    screen -S minecraft -p 0 -X stuff "$1^M"
}

say_this "say Saving world"
say_this "save-off"
say_this "save-all"
...

C'est avec ssh!

#!/bin/bash

say_this()
{
    # Dont forget to set NAME or whatever
    ssh -p 8989 192.168.1.101 screen -S $NAME -p 0 -X stuff \"$1^M\"
}

say_this "say test"
say_this "say !@#$%^&*()<>?This string will work!"
fuzzyfreak
la source
Nice and Concise ... Bienvenue sur U & L
eyoung100