Stdin, stdout, stderr pour un promt ubuntu
Fermé
nar6du14
Messages postés
459
Date d'inscription
dimanche 27 décembre 2009
Statut
Membre
Dernière intervention
7 décembre 2013
-
30 mars 2012 à 22:45
nar6du14 Messages postés 459 Date d'inscription dimanche 27 décembre 2009 Statut Membre Dernière intervention 7 décembre 2013 - 31 mars 2012 à 14:45
nar6du14 Messages postés 459 Date d'inscription dimanche 27 décembre 2009 Statut Membre Dernière intervention 7 décembre 2013 - 31 mars 2012 à 14:45
A voir également:
- Stdin, stdout, stderr pour un promt ubuntu
- Ubuntu iso - Télécharger - Systèmes d'exploitation
- Ubuntu 24.04 - Accueil - Ubuntu
- Ubuntu 32 bits - Télécharger - Systèmes d'exploitation
- Linux mint ou ubuntu - Guide
- Hdmi ubuntu - Forum Ubuntu
2 réponses
mamiemando
Messages postés
33394
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
28 novembre 2024
7 803
31 mars 2012 à 12:46
31 mars 2012 à 12:46
Pour moi ce que tu dis n'a pas vraiment de sens.
Afin qu'on se comprenne, un petit point sur la terminologie :
- Un prompt décrit la mise en forme ton invite de commande dans un shell (par exemple "(mando@aldur) (~) $"). Tu le vois par exemple en tapant "echo $PS1".
- Un shell est un processus (bash, ksh, zsh, tcsh...) qui interprète des commandes (shell) par exemple au travers d'un terminal ou d'une console.
- Un terminal est un programme graphique qui embarque un shell (par exemple konsole, gnome-terminal, eterm, xterm)...
- Une console correspond à un environnement en mode texte (tty1, tty2...) accessibles en général avec les combinaisons de touches "ctrl alt f1", "ctrl alt f2" etc...
Au sens d'un processus, que ce soit firefox, ls, bash, bref n'importe quel processus qui apparaît dans une ligne de la commande "ps aux", tu peux parler
- d'une entrée
- d'une sortie
- d'une sortie d'erreur
Ainsi si on devait schématiser un processus il ressemblerait à ceci :
Par défaut un processus va lire dans l'entrée standard (/dev/stdin) écrire dans la sortie standard (/dev/stdout) et écrire ces messages d'erreur dans la sortie d'erreur standard (/dev/stderr). Mais fondamentalement c'est un "câblage" parmi une infinité. Ainsi un pipe (|) consiste simplement à câbler la sortie d'un processus P1 sur l'entrée d'un processus P2.
Exemple : le processus grep ici lit sur son flux d'entrée le flux généré par cat.
Si tu tapais directement :
... alors comme grep lit dans l'entrée standard (comportement par défaut de grep), il attendra que tu tapes du texte (puis sur entrée) pour voir s'il filtre ou non la ligne qu'il a reçu, puis la réécrira sur sa sortie (la sortie standard, ce qui se traduit dans ce cas précis par "écrire dans le terminal"). Ton shell ensuite rattrape les flux qui sont sortis (ici de grep) pour les réécrire sur la console.
Les câblages à l'aide de pipe se réalisent en C avec des fonctions comme popen, pipe, pipe2 etc...
Maintenant revenons à ton problème. Je pense que c'est une mauvaise idée de câbler un programme python à un gnome-terminal, car il n'est pas forcément installé sur une machine (déjà sur une machine il n'y a pas forcément de terminal graphique). Comme le montre ce que je viens de t'expliquer, si tu n'utilises pas en python des fonction dans l'esprit de popen tu risques d'être rapidement bloqué car tu ne seras pas vers quel processus envoyer ton flux. En admettant que tu récupères le PID de ton processus gnome terminal (sachant que si tu l'ouvres depuis python avec popen ça doit être faisable), il faudrait ensuite "deviner" comment parler à gnome terminal pour qu'il écrive des choses (et je ne pense même pas que ce soit possible sans passer par une api gnome).
Pour moi la bonne approche serait que l'utilisateur lance lui-même son terminal et ton programme dedans. En effet celui-ci peut vouloir que le résultat soit écrit dans un terminal, un fichier, un socket bref quelque chose que tu ne peux pas deviner. Ce n'est donc pour moi pas à ton programme de gérer ça.
Ainsi on peut imaginer un script shell qui appelle ton script python, redirige sa sortie dans un fichier texte et ensuite l'ouvre par exemple gedit :
On peut aussi simplement supposer que tu lances directement ton programme comme suit :
... et que dans deux autres shells tu lances respectivement :
... pendant que ton programme tourne. Ainsi tu verras s'afficher en temps réel le flux qui est écrit dans ces deux fichiers.
Bonne chance
Afin qu'on se comprenne, un petit point sur la terminologie :
- Un prompt décrit la mise en forme ton invite de commande dans un shell (par exemple "(mando@aldur) (~) $"). Tu le vois par exemple en tapant "echo $PS1".
- Un shell est un processus (bash, ksh, zsh, tcsh...) qui interprète des commandes (shell) par exemple au travers d'un terminal ou d'une console.
- Un terminal est un programme graphique qui embarque un shell (par exemple konsole, gnome-terminal, eterm, xterm)...
- Une console correspond à un environnement en mode texte (tty1, tty2...) accessibles en général avec les combinaisons de touches "ctrl alt f1", "ctrl alt f2" etc...
Au sens d'un processus, que ce soit firefox, ls, bash, bref n'importe quel processus qui apparaît dans une ligne de la commande "ps aux", tu peux parler
- d'une entrée
- d'une sortie
- d'une sortie d'erreur
Ainsi si on devait schématiser un processus il ressemblerait à ceci :
entrée | processus | \--> sortie \--> sortie d'erreur
Par défaut un processus va lire dans l'entrée standard (/dev/stdin) écrire dans la sortie standard (/dev/stdout) et écrire ces messages d'erreur dans la sortie d'erreur standard (/dev/stderr). Mais fondamentalement c'est un "câblage" parmi une infinité. Ainsi un pipe (|) consiste simplement à câbler la sortie d'un processus P1 sur l'entrée d'un processus P2.
Exemple : le processus grep ici lit sur son flux d'entrée le flux généré par cat.
cat /etc/fstab | grep dev
Si tu tapais directement :
grep dev
... alors comme grep lit dans l'entrée standard (comportement par défaut de grep), il attendra que tu tapes du texte (puis sur entrée) pour voir s'il filtre ou non la ligne qu'il a reçu, puis la réécrira sur sa sortie (la sortie standard, ce qui se traduit dans ce cas précis par "écrire dans le terminal"). Ton shell ensuite rattrape les flux qui sont sortis (ici de grep) pour les réécrire sur la console.
Les câblages à l'aide de pipe se réalisent en C avec des fonctions comme popen, pipe, pipe2 etc...
Maintenant revenons à ton problème. Je pense que c'est une mauvaise idée de câbler un programme python à un gnome-terminal, car il n'est pas forcément installé sur une machine (déjà sur une machine il n'y a pas forcément de terminal graphique). Comme le montre ce que je viens de t'expliquer, si tu n'utilises pas en python des fonction dans l'esprit de popen tu risques d'être rapidement bloqué car tu ne seras pas vers quel processus envoyer ton flux. En admettant que tu récupères le PID de ton processus gnome terminal (sachant que si tu l'ouvres depuis python avec popen ça doit être faisable), il faudrait ensuite "deviner" comment parler à gnome terminal pour qu'il écrive des choses (et je ne pense même pas que ce soit possible sans passer par une api gnome).
Pour moi la bonne approche serait que l'utilisateur lance lui-même son terminal et ton programme dedans. En effet celui-ci peut vouloir que le résultat soit écrit dans un terminal, un fichier, un socket bref quelque chose que tu ne peux pas deviner. Ce n'est donc pour moi pas à ton programme de gérer ça.
Ainsi on peut imaginer un script shell qui appelle ton script python, redirige sa sortie dans un fichier texte et ensuite l'ouvre par exemple gedit :
#!/bin/sh out=$(mktemp) err=$(mktemp) editor="gedit" prgm="/home/toto/programme.py" python $prgm 1> $out 2> $out $editor $out $err rm -f $out $err
On peut aussi simplement supposer que tu lances directement ton programme comme suit :
python /home/toto/programme.py 1> /tmp/out.txt 2> /tmp/err.txt
... et que dans deux autres shells tu lances respectivement :
tail -f /tmp/out.txt tail -f /tmp/err.txt
... pendant que ton programme tourne. Ainsi tu verras s'afficher en temps réel le flux qui est écrit dans ces deux fichiers.
Bonne chance
nar6du14
Messages postés
459
Date d'inscription
dimanche 27 décembre 2009
Statut
Membre
Dernière intervention
7 décembre 2013
64
Modifié par nar6du14 le 31/03/2012 à 14:50
Modifié par nar6du14 le 31/03/2012 à 14:50
merci de m'avoir repondu, tes éclaircissements sont justes. Je vais devoir me mettre à la programmation sous linux et apprendre tous ces éléments importants. Tu as tout de même compris ce que je voulais faire mais il faudrait peut être que je t'apporte un plus de détails dans ce que je veux faire.
L'application que je veux écrire n'est pas vraiment du style client/serveur mais elle exploite tout la technologie des socket pour le faire. Ce que je veux dire c'est que le programme serveur est juste là pour donner des infos sur chaque socket cliente et que du coté des programmes clients sera installée toute une pile de services. De ce fait, je veux créer une interface graphique qui me rendra compte coté serveur des connexions clientes en cours: je peux imaginer une zone à boutons, chaque bouton correspondant à un client connecté sur la machine serveur. Si je clique sur n'importe quel bouton, un terminal devrait pouvoir s'ouvrir: ce terminal correspondant à la connexion du serveur avec le client en question. Tout ce qui sera tapé sur ce terminal coté serveur doit etre transféré au dit client à travers le réseau (via la socket) et tout ce qui sera renvoyé par le coté client doit s'afficher sur le terminal.
C'est ce qui explique mon besoin d'ouvrir plusieurs terminaux du style gnome terminal et de lié chacun d'eux à une connexion client/serveur et une seule.
L'application que je veux écrire n'est pas vraiment du style client/serveur mais elle exploite tout la technologie des socket pour le faire. Ce que je veux dire c'est que le programme serveur est juste là pour donner des infos sur chaque socket cliente et que du coté des programmes clients sera installée toute une pile de services. De ce fait, je veux créer une interface graphique qui me rendra compte coté serveur des connexions clientes en cours: je peux imaginer une zone à boutons, chaque bouton correspondant à un client connecté sur la machine serveur. Si je clique sur n'importe quel bouton, un terminal devrait pouvoir s'ouvrir: ce terminal correspondant à la connexion du serveur avec le client en question. Tout ce qui sera tapé sur ce terminal coté serveur doit etre transféré au dit client à travers le réseau (via la socket) et tout ce qui sera renvoyé par le coté client doit s'afficher sur le terminal.
C'est ce qui explique mon besoin d'ouvrir plusieurs terminaux du style gnome terminal et de lié chacun d'eux à une connexion client/serveur et une seule.