[shell] Récupérer stdin

Bonsoir,
je cherche un moyen de récupérer dans un script shell (bash par exemple) le flux d’entrée.
Par exemple, le script doit pouvoir traiter comme une chaine de caractère le retour de la commande ls, si je tape :

ou

J’ai eu beau chercher sur le net, je n’arrive à trouver que des exemple de récupération de ce que l’utilisateur tape seulement une fois que le script est lancé. Peut-être ce que je veux n’est pas possible en shell?

Salut,

voici une solution basique :

input=$(cat -)
printf "$input"

Impossible is nothing.

Ce que tu veux c’est créer un filtre.

[code]#!/bin/sh

while read line ; do
echo "suffixe ${line}"
done[/code]

La version de Iroy fonctionne aussi, mais le problème c’est que tu dois attendre la fin de la lecture de l’entrée pour commencer à travailler. Ça va à l’encontre de l’architecture des pipelines.

D’accord, mais avec ces méthodes, si je demande à l’utilisateur une entrée (via un read variable), elle n’est pas appelée…

En fait, le “entrée” lorsqu’on valide la commande est enregistrée directement dans ce read…

#!/bin/sh
n=1
while read line ; do
    echo "$n ${line}"
    n=$((n+1))
done
echo "fini"
read -p "Numéro : " NL

#!/bin/bash n=1 while [[ $n -lt 4 ]] ; do read line echo "$n ${line}" n=$((n+1)) done echo "fini" exec 0>&- exec 0</dev/pts/0 read -p "Numéro : " NL echo "fini"
On lis ce qu’on veux sur l’entrée standard. Quand on en a raz le bol on ferme le descripteur de fichier 0 (l’entrée standard), puis on le ré-ouvre en pointant sur le terminal.

[quote=“MisterFreez”]#!/bin/bash n=1 while [[ $n -lt 4 ]] ; do read line echo "$n ${line}" n=$((n+1)) done echo "fini" exec 0>&- exec 0</dev/pts/0 read -p "Numéro : " NL echo "fini"
On lis ce qu’on veux sur l’entrée standard. Quand on en a raz le bol on ferme le descripteur de fichier 0 (l’entrée standard), puis on le ré-ouvre en pointant sur le terminal.[/quote]
Merci beaucoup pour ces détails. Ce n’est pas anodin quand même.

Nouveau problème cela dit. “entrée” ne permet pas de valider le read et de passer à la suite…

Ça ne sera pas plus simple dans un autre langage, le principe restera le même.
[ul]
[li]fermer son entrée standard[/li]
[li]en ouvrir un nouveau pour pointant le shell[/li][/ul]

Chez moi si. Tu utilise exactement le code que j’ai montré ?

Non, pas exactement, car le tiens limite le nombre de lignes à 4 :

#!/bin/sh
n=1
while read line ; do
    echo "$n ${line}"
    n=$((n+1))
done
echo "---"
exec 0>&-
exec 0</dev/pts/0
echo "test"
read -r test

Ça me paraît plus simple en C

Plus lisible peut être mais pas plus simple. Il faut avoir bien compris le fonctionnement pour savoir que le open(2) qui suit un close(fd) avec fd = 0 renverra 0 parce qu’il utilise le premier de libre. Après essaie, tu n’es pas obligé de fermer le descripteur dans le script bash.

Je n’ai pas reproduit ton problème. Avant le read -r lance :

J’ai dit “paraît” plus simple, car on a accès à stdin directement. Mais si on veut faire les choses très correctement, ce n’est pas très simple (il n’y a qu’à voir le code de cat…)
Lorsque je rajoute ça : ls -l "/proc/$$/fd"
Voici ce qui est affiché :

total 0 lr-x------ 1 xavier xavier 64 mai 2 08:25 0 -> /dev/pts/0 lrwx------ 1 xavier xavier 64 mai 2 08:25 1 -> /dev/pts/4 lr-x------ 1 xavier xavier 64 mai 2 08:25 10 -> /home/xavier/.Scripts/cldmenu lrwx------ 1 xavier xavier 64 mai 2 08:25 2 -> /dev/pts/4 lrwx------ 1 xavier xavier 64 mai 2 08:25 3 -> /dev/tty7

J’ai pas encore trouvé de bon moyen de choisir le bon pseudo terminal. Tu peux néanmoins faire ça:

ça devrait marcher sinon :

pstname="$(ls -l /proc/self/fd/1 | sed 's/.*-> //')" exec 0<"${pstname}"

Cette commande ne renvoie pas quelque chose du type /dev/pts/2 , mais un truc du type pipe:[94476]

Et ce, même en remplaçant le sed par un awk ‘{print $NF}’ ou équivalent avec cut…

Normal tu redirige vers un pipe.

Donc en cherchant un peu plus, il y a n terminaux virtuels esclaves rattachés à un seul terminal virtuel client. Cela permet d’avoir un seul clavier et plusieurs pseudo terminaux. Chacun de ses n pseudo terminaux correspond à un terminal virtuel de ta session graphique. Les terminaux qui utilisent directement getty ont, eux, un tty à eux. Pour trouver le bon fichier virtuel à ouvrir, il y a plusieurs solutions :
[ul]
[li]la commande tty[/li]
[li]ps ax | awk -v pid=$$ '$1~pid{print “/dev/”$2}[/li][/ul]

Là ça commence à être une solution qui me plaît (c’est fiable et mieux maitrisé).

Wahou! Merci pour toutes tes recherches! C’est plus que je le demandais!
Je connaissais pour le tty, mais pas pour un terminal graphique.

Aurais-tu des sources à ce sujet?

Pas vraiment c’est très empirique comme recherche avec un chouia de recherche sur internet pour trouver des points particuliers.

C’est pas grave, merci quand même!
Lors de mes recherches, j’arrivais très vite à la limite de ma compréhension…