Récupérer entrée standard

Résolu/Fermé
Jpo - Modifié par mamiemando le 30/08/2012 à 10:45
 Jpo - 1 sept. 2012 à 20:48
Bonjour, je suis débutant dans le monde de linux et parmi tous les obstacles qui se présentent en voila un sur le quel je bloque :(
J'aimerais savoir si il existe un moyen de récupérer dans un terminal B l'entrée standard d'un script lancé dans un terminal A.

Concrètement, j'ai un serveur que je lance grâce a un script qui garde la main(je suis pas sur du terme mais le script reste lancé dans la console, le prompt ne revient que si je stop le script). Je souhaite évidemment garder ce comportement, car c'est à partir de la que je peux communiquer avec le serveur, l'arrêter, le redémarrer etc ...
Pour l'instant j'utilise screen dans le quel je laisse mon script tourner.
Ensuite, chaque jour je fais un backup des fichiers qui m'intéressent, mais pour cela je suis obligé de lancer screen, stopper mon serveur, exécuter mon script de backup, et relancer mon serveur.
J'aimerais automatiser tout ça en lançant mon backup grâce à cron, et j'aimerais surtout qu'il arrête mon serveur proprement, je ne veux pas de kill ou quoi que ce soit dans ce goût la, car lorsque que je l'arrête à la main le serveur prend la peine de sauvegarder un certain nombre de fichiers.
Dans l'idéal mon script de backup devrait envoyer "stop" dans le terminal ou mon script serveur est lancé avant de copier ce qui l'intéresse et ensuite relancer le serveur dans le terminal ou il était a l'origine.
J'aimerais donc savoir si c'est possible, et si oui comment faire pour envoyer un message d'un terminal à un autre.
Merci d'avance :)

7 réponses

@tuxboy
lorsque je fais
cat < /dev/pts/3
dans pst2 et que j'écris dans pts3 j'obtiens un comportement assez peu concluant.
Si je tape "Hello world" par exemple je me retrouve avec "eloworl" dans pts2 et "hl d" dans pts3. Si quelqu'un a une idée du pourquoi les caractères sont éparpillés comme ça ça m'intéresse :)

J'ai testé
echo && cat > /dev/pts/2
depuis pts3, tout ce que je tape dans pts3 s'affiche bien dans pts2 mais il ne les interprète pas
echo "hello"
echo -e "hello\n"

se contentent d'afficher "echo "hello"" et "echo -e "hello\n"" tel quel dans pts2.
-----
@zipe31
j'ai fini par trouver une solution donc je n'ai pas testé xdotool, mais merci quand meme.
-----
@mamiemando
c'est un serveur minecraft, il est écrit en java et donc pas vraiment spécifique a linux.
-----
J'ai finalement trouvé une solution, screen permet d'envoyer des commandes directement à une de ses fenêtres, je n'ai donc qu'à laisser tourner mon serveur dans screen comme je fais pour le moment et l'arrêter dans mon script de backup avec une commande du genre
screen -p id_window -X eval 'stuff "ma_commande\015"'


Merci pour votre aide :)
2
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
30 août 2012 à 10:59
Pour moi ce n'est pas la bonne approche, tu devrais plutôt regarder comment un démon (programme qui tourne en arrière plan, par exemple un serveur ssh) fonctionne.

Traditionnellement on crée un script shell dans /etc/init.d qui sert à le lancer/stopper/démarrer. Ce script est responsable de lancer et tuer le démon proprement. Une fois créé il est possible d'instancier ce script (shell) via la commande service (par exemple service ssh start). Normalement la structure du fichier est assez cadrée. Sous debian tu peux t'inspirer d'un squelette (/etc/init.d/skeleton) ou repartir d'un script existant (par exemple /etc/init.d/ssh).

Afin que ce script soit lancé automatiquement au démarrage (plus précisément déclencher implicitement un "start" ou un "stop" implicite quand on bascule dans un runlevel donné) on est ensuite sensé créer les liens symboliques appropriés dans les dossiers /etc/rc*.d. Sous debian ceci se fait par exemple avec la commande update-rc.d.

Maintenant, rentrons un peu plus dans le détail de ce que font le script shell et le démon. Le script stocké utilise typiquement un fichier dans lequel est stocké le pid du démon instancié (stocké généralement dans /var/run) pour savoir quel processus tuer. Sous debian par exemple c'est ce que permet de gérer start-stop-daemon.

Afin de garantir que le démon n'est instancié qu'une seule fois (dans mon exemple seul un serveur ssh peut écouter sur le port 22 donc on ne peut instancier qu'un démon), le démon (pas le script) est sensé vérifier qu'il n'est pas déjà lancé (par exemple en créant un fichier de verrou dans /var/lock ou /var/subsys/lock qu'il détruira une fois stoppé).

Note qu'une fois rendu là, ton programme tourne en arrière plan. Donc pas besoin de le mettre dans un screen ou un nohup (d'ailleurs dans ton cas nohup serait plus approprié). De plus pas besoin qu'il garde la main car ton script dans /etc/init.d permet de le stopper et démarrer à volonté (plus besoin de cron non plus d'ailleurs). On peut tout à fait imaginer que dans le script shell, tu déclenches ton backup au moment de faire un "stop".

Au niveau du démon, c'est à ton programme de rattraper le kill pour s'arrêter proprement. Le mieux serait de repartir d'un tutoriel.

Enfin, envoyer un message d'un terminal à un autre n'a pas vraiment de sens (ni d'un point de vue linux, ni pour ce que tu veux faire). En réalité tu veux communiquer une information entre deux processus. Ça peut se faire via un pipe si les deux processus sont instantiables au même moment (exemple : find / | grep /home) ou dans ton code en créant un pipe (appelé aussi tube). Autre approche, plus simple, tu rediriges le flux de la sortie standard dans un fichier (voir opérateurs 1> et 1>>, aussi notés > et >>) et tu manipules ce fichier à posteriori.

Bonne chance
0
Merci pour ta réponse.
Ton idée semble en effet plus séduisante que mon bricolage.
Cependant j'ai besoin que ce script garde la main, c'est un serveur de jeu, et grâce à cette "entrée" je peux par exemple gérer les joueurs connectés, modifier certains paramètres d'une partie etc... Donc avec un nohup je me retrouve dans l'incapacité de communiquer directement avec le serveur.
Je vais tenter de résoudre le problème du backup avec un demon. Mais il me reste toujours une solution à trouver pour garder cette communication avec mon script "ouverte" quelque part.
Puisque tu me parles de redirection, est ce qu'il serait par exemple possible de rediriger l'entrée standard de mon script depuis un fichier dans le quel je viendrais écrire ce que je veux transmettre au serveur ?
0
tuxboy Messages postés 994 Date d'inscription lundi 23 juillet 2012 Statut Membre Dernière intervention 28 mai 2019 189
Modifié par tuxboy le 30/08/2012 à 21:59
Peut-être regarder du côté de /dev/pts
Tu ouvres donc deux terminaux, dans le premier tu lances ton script
Dans le second, tu regardes :
ls -ls /dev/pts     

puis
ps


et tu remplaces les ??? par le bon numéro retrouvé ci-dessus dans
cat </dev/pts/???


(

ou bien tu lances ton script en collant :
&& cat > /dev/pts/???

)
par exemple :
echo && cat > /dev/pts/0
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
31 août 2012 à 08:02
Salut,

Essaie de voir du côte de "xdotool", voir ce thread...
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
31 août 2012 à 10:43
Cependant j'ai besoin que ce script garde la main, c'est un serveur de jeu, et grâce à cette "entrée" je peux par exemple gérer les joueurs connectés, modifier certains paramètres d'une partie etc... Donc avec un nohup je me retrouve dans l'incapacité de communiquer directement avec le serveur.

C'est quoi ce serveur de jeu ? Parce que là son mode de fonctionnement me paraît bien surprenant. En général un serveur sous linux n'offre pas directement une interface interactive comme tu sembles le suggérer.

Au mieux ils supportent des appels particuliers pour réaliser des tâches particulières. Par exemple au travers de requêtes sql, on peut modifier la configuration d'un serveur mysql, d'autres serveurs sont pilotables au travers d'appel xmlrpc etc... Mais dans tous les cas ils sont lancés en arrière plan.

Sinon n'hésite pas explorer les pistes suggérées par zipe31 et tuxboy.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
31 août 2012 à 23:56
Juste pour info (tu noteras que comme prévu, la stratégie consiste bien à écrire un service dans /etc/init.d) :
http://www.artduweb.com/tutoriels/minecraft-server

Mais bon si la solution actuelle te convient tant mieux ;-)
0
Mais je note aussi qu'il se sert de screen pour garder cette interaction avec le serveur :p
Je tenais absolument à garder ce comportement parce que je me contente d'héberger le serveur sans jouer a minecraft, je n'ai donc que ce moyen de communication avec le serveur.
Je te remercie quand même pour le lien, son script est évidemment bien plus propre que le mien :)
0