Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 03/05/2010, à 14:52

AnsuzPeorth

read < FIFO Appel système interrompu

Bjr,
J'ai un petit problème que je n'arrive pas à élucider ! (j'y suis depuis un moment...)

#!/bin/bash
rm /tmp/FIFO
mkfifo /tmp/FIFO
function Num()
{
for n in {0..10}
    do
        echo $n
         #sleep 0.2
    done
}

while true
    do
       read ligne < /tmp/FIFO
       [ "$ligne" = "stop" ] && break
       [ "$ligne" = "go" ] && Num &
    done

Dans une autre console :

echo go > /tmp/FIFO
echo stop > /tmp/FIFO

En l'état cela fonctionne comme voulu , mais il suffit de décommenter le sleep, le message d'erreur apparait et la boucle continue..

/tmp/FIFO: Appel système interrompu

Pour pouvoir garder le sleep, soit je ne lance pas la fonction en arrière plan, soit je vide la variable $ligne en début de boucle.

J'aimerais comprendre ce phénomène, pourquoi le sleep arrête le branchement au fifo ?

C'est bien jolie de contourner les problèmes, l'idéal serait de ne pas les avoir smile

Si qql'un pouvait me venir en aide ... Merci .

Dernière modification par AnsuzPeorth (Le 03/05/2010, à 14:53)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#2 Le 03/05/2010, à 15:21

sputnick

Re : read < FIFO Appel système interrompu

Si tu lance ta fonction en tache de fond, le temps d'afficher 1 à 10 et ta boucle a déjà tournée.
Si tu rajoute un wait avant le done final, cela va marcher avec le sleep et l'envoi en tache de fond.


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#3 Le 03/05/2010, à 15:29

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Oui mais la boucle est bloquée et ce n'est pas l'effet voulu neutral

Merci qd même !

Dernière modification par AnsuzPeorth (Le 03/05/2010, à 15:42)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#4 Le 03/05/2010, à 15:37

johndo

Re : read < FIFO Appel système interrompu

Pour lire un pipe avec read, il me semble qu'il est nécessaire d'utiliser l'option -u.

#!/bin/bash
[ -p /tmp/FIFO ] && rm /tmp/FIFO
mkfifo /tmp/FIFO
function Num()
{
for n in {0..10}
    do
        echo $n
         #sleep 0.2
    done
}
exec 4</tmp/FIFO
while true
    do
       read -u 4 ligne
       [ "$ligne" = "stop" ] && break
       [ "$ligne" = "go" ] && Num &
done

Je ne peux pas le tester. Ma version du bash au TAF n'accèpte pas cette option.

Hors ligne

#5 Le 03/05/2010, à 16:04

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Et non plus ... Tjrs le message ...! (il faut mettre le exec dans la boucle sinon ca boucle non-stop !?)

Par contre plus besoin du vider $ligne, read doit le faire.

Merci qd même, j'adopte l'option -u smile

edit: où trouver le man read, dans coreutils je ne l'ai pas trouvé, et sur le net pas d'option -u

Dernière modification par AnsuzPeorth (Le 03/05/2010, à 16:09)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#6 Le 03/05/2010, à 16:08

sputnick

Re : read < FIFO Appel système interrompu

Wé, ça semble pas mal fonctionner :

#!/bin/bash

rm -f /tmp/fifo
mkfifo /tmp/fifo

Num()
{
    for n in {0..10}; do
        echo $n
        sleep 0.2
    done
}

exec 4</tmp/fifo

while true; do
   read -u 4 ligne
   [ "$ligne" = "stop" ] && break
   [ "$ligne" = "go" ] && Num &
done

exec 4<&-

J'ai rajouté la fermeture du FD4


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#8 Le 03/05/2010, à 16:14

AnsuzPeorth

Re : read < FIFO Appel système interrompu

sputnick a écrit :

Wé, ça semble pas mal fonctionner :

Oui mais la boucle ne s'arrête, elle ne reste pas bloquée sur le read !
Soit mettre le exec dans la boucle ou un petit sleep pour ne pas monter dans le cpu.
Le sleep c'est pas top !
Mettre le exec dans la boucle, c'est grave docteur ???

edit: merci Frafa ;)

Dernière modification par AnsuzPeorth (Le 03/05/2010, à 16:21)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#9 Le 03/05/2010, à 17:13

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Bon, même si c'est pas parfait, je vais opter pour le sleep, ca m'enlève tous les bugs smile
Niveau ressources, au repos je suis entre 1 et 2%, pour un sleep 0.5 je bloque sur 2 %, un sleep 0.1 entre 2 et 3 %.
C'est pas bien méchant surtout que ce n'est qu'un HT 3 Ghz ...!

Le sujet reste ouvert, si qql'un trouve mieux smile

En tout cas merci encore tous, ca va me permettre de continuer mon projet, temps que ce petit détails n'était pas résolu, je ne voulais pas aller trop loin !


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#10 Le 03/05/2010, à 18:50

Totor

Re : read < FIFO Appel système interrompu

Salut,

Je n'ai pas d'erreur avec les solutions proposées par johndo et sputnick (donc avec ou sans la fermeture du fd et sans le sleep) ...
et la boucle s'arrête bien lorsqu'on lui envoie "stop".

la seule erreur que j'ai est avec ta première version.

Essaie avec ceci :

#!/bin/bash

rm -f /tmp/fifo
mkfifo /tmp/fifo

Num()
{
    for n in {0..10}; do
        echo $n
#        sleep 0.2
    done
}

exec 4</tmp/fifo

while true; do
   read -u 4 ligne
   [ "$ligne" = "stop" ] && break
   [ "$ligne" = "go" ] && { Num &; disown -h %+; }
done

exec 4<&-

essaie également sans l'option -h mais ça ne devrait pas changer grand chose

EDIT : quel bash as-tu ?
je suis en 4.1.5(1)-release (x86_64-pc-linux-gnu)

Dernière modification par Totor (Le 03/05/2010, à 18:59)


-- Lucid Lynx --

Hors ligne

#11 Le 03/05/2010, à 19:33

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Oui mais non, justement je voulais garder le sleep (sortie du contexte celle là...!)

Ce script ne fonctionne pas non plus (même sans sleep):
j'ai déjà une erreur, j'ai été obligé déplier les accolades pour la commande disown.

 Erreur de syntaxe près du symbole inattendu « ; »

lorsque je le lance j'ai cette sortie:

disown: %+ : tâche inexistante

Ensuite le script par en boucle infini.

Avec ou sans le sleep, pareil ....

GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)

La solution, pour l'instant c'est de mettre un petit sleep dans la boucle while, et la laisser faire ... C'est pas génial !

ps: mon premier script dans l'état, sans le sleep, fonctionnait, c'est quand j'y ajoutais le sleep (de la boucle for) que ca partait en boucle infini.

Dernière modification par AnsuzPeorth (Le 03/05/2010, à 19:38)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#12 Le 03/05/2010, à 22:47

AnsuzPeorth

Re : read < FIFO Appel système interrompu

J'ai essayé en live (donc dernière version de bash) même topo ...!
Ca boucle infini, donc usage cpu à fond .

Dernière modification par AnsuzPeorth (Le 04/05/2010, à 18:43)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#13 Le 04/05/2010, à 00:30

sputnick

Re : read < FIFO Appel système interrompu

Une version qui ne devrais quasi pas consommer de CPU :

#!/bin/bash

trap 'exec 4<&-; rm -f /tmp/fifo' 0 1 2 3 15

mkfifo /tmp/fifo
exec 4</tmp/fifo

main()
{
    for n in {0..10}; do
        echo $n
        sleep 0.2
    done
}

while read 2>/dev/null -u 4 line; do
    [[ $line == stop ]] && break

    if [[ $line == go ]]; then
        main &
        disown -h %+
    fi

    inotifywait &>/dev/null -e modify /tmp/fifo
done

On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#14 Le 04/05/2010, à 18:40

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Bien vu le coup du inotify, j'y ai pas pensé, alors que j'utilisais cette outils avant de vouloir lire un FIFO direct .... des fois !
Enfin, malheureusement, j'ai passé je sais pas combien de temps à essayer de l'intégrer, mais il fait perdre en réactivité, parfois même, ca bloque le tout ... (le temps de lancer la commande)
Je garde l'idée dans un coin de ma tête, on sait jamais.
Et puis, une boucle avec un sleep, ca consomme pas grand chose !

D'ailleurs, personne ne sait comment connaître l'utilisation processeur pour une appli (top n'est pas assez précis, la boucle lancée, la consommation reste à 0)

Merci !

ps: je ne passe pas en résolu, des fois qu'il existerait qd même une solution avec read direct sur le fifo, sans que ca boucle infini smile
ps2: je pense à ça ... Je pourrais très bien intégrer du code python dans le bash ...:)  Je vais m'y pencher dès que j'aurais un peu de temps....

Dernière modification par AnsuzPeorth (Le 04/05/2010, à 18:41)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#15 Le 04/05/2010, à 19:04

sputnick

Re : read < FIFO Appel système interrompu

Ben direct sur le fifo ça marche nickel :

#!/bin/bash

trap 'rm -f /tmp/fifo' 0 1 2 3 15

mkfifo /tmp/fifo

main()
{
    for n in {0..10}; do
        echo $n
        sleep 0.2
    done
}

while read line; do
    [[ $line == stop ]] && break

    if [[ $line == go ]]; then
        main &
        disown -h %+
    fi

    inotifywait &>/dev/null -e modify /tmp/fifo
done < /tmp/fifo

On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#16 Le 04/05/2010, à 19:28

Totor

Re : read < FIFO Appel système interrompu

ouais, je comprends pas car toutes les versions ci-dessous fonctionnent très bien :

#!/bin/bash

[ ! -p /tmp/fifo ] && mkfifo /tmp/fifo

Num()
{
    for n in {0..10}; do
        echo $n
        sleep 0.1
    done
}

exec 4</tmp/fifo

while true; do
   read -u 4 ligne 
   [ "$ligne" = "stop" ] && break
   [ "$ligne" = "go" ] && { 
		Num &
		disown -h %+ ; 
	}
done

exec 4<&-

# ---------------------------
#!/bin/bash

[ ! -p /tmp/fifo ] && mkfifo /tmp/fifo

Num()
{
    for n in {0..10}; do
        echo $n
        sleep 0.1
    done
}

exec 4</tmp/fifo

while true; do
   read -u 4 ligne 
   [ "$ligne" = "stop" ] && break
   [ "$ligne" = "go" ] && Num &
done

exec 4<&-

# ---------------------------------------
#!/bin/bash

trap 'rm -f /tmp/fifo' 0 1 2 3 15

[ ! -p /tmp/fifo ] && mkfifo /tmp/fifo

main()
{
    for n in {0..10}; do
        echo $n
        sleep 0.2
    done
}

while read line; do
    [[ $line == stop ]] && break

    if [[ $line == go ]]; then
        main &
        disown -h %+
    fi
done < /tmp/fifo

aucun problème chez moi hmm

sinon :
watch -d -n 1 'ps -o pid,%cpu -p <pid> --no-headers'
mais je pense que cela revient à utiliser top

Dernière modification par Totor (Le 04/05/2010, à 19:32)


-- Lucid Lynx --

Hors ligne

#17 Le 04/05/2010, à 20:45

AnsuzPeorth

Re : read < FIFO Appel système interrompu

@Sputnick
Ton dernier exemple utilise encore inotify, et le temps que la commande se lance dans mon script, ca produit des bugs ...!
Je veux un truc qui consomme pas et soit réactif (je pourrais poser des sleep un peu partout pour laisser le temps à inotify, mais c'est pas terrible !)

@Totor
Chez moi tous ces exemples fonctionne, mais ils tournent en boucle infini (j'ai placé un echo, et il suffit de voir les ressources CPU).


Par contre j'ai réussi à faire ce que je voulais pour l'exemple, mais dans mon script, le problème du pipe brisé revient (dû aux reconnections sur le fifo ...)

C'est simple en plus smile (je m'étais déjà amuser avec des boucles imbriquées ... arf, mémoire de poisson rouge ...)

#!/bin/bash
rm -f /tmp/fifo
mkfifo /tmp/fifo
main()
{
    for n in {0..10}; do
        echo $n
        sleep 0.2
    done
}

while read ligne; do

    [[ "$ligne" == "go" ]] && main &

done < <(while true; do

    read entree < /tmp/fifo
    [[ "$entree" == "stop" ]] && break
     echo $entree

done)

exit

Il me faudrait la même chose, sans reconnections sur le fifo (read -u), mais sans boucle infini ni inotify ....
Doit bien avoir moyen de résoudre ça en bash ...!


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#18 Le 04/05/2010, à 21:03

Totor

Re : read < FIFO Appel système interrompu

chez moi le comportement me semble correcte. je ne comprends donc pas cet aspect de boucle infinie hmm

le read bloque bien jusqu'à ce qu'il lise quelque chose du pipe. le while ne consomme donc pas de cpu.
lorsqu'il lit "go", il lance bien l'affichage des chiffres en arrière plan (qui s'exécute correctement). En parallèle, le read reçoit "stop" provoquant le "break" et donc la sortie de la boucle.

A moins que chez toi, le break effectue la sortie de l'affichage .. (ce qui serait vraiment étonnant) yikes
Si c'est le cas, as-tu essayé ceci :

#!/bin/bash

[ ! -p /tmp/fifo ] && mkfifo /tmp/fifo

Num()
{
    for n in {0..10}; do
        echo $n
        sleep 0.1
    done
}

exec 4</tmp/fifo

ligne=
while [ "${ligne}" != "stop" ]; do
   read -u 4 ligne
   [ "$ligne" = "go" ] && Num &
done

exec 4<&-

Dernière modification par Totor (Le 04/05/2010, à 21:05)


-- Lucid Lynx --

Hors ligne

#19 Le 04/05/2010, à 21:12

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Ton dernier exemple lance la numérotation et part en boucle infini, la boucle infini s'arrête lorsqu'elle recoit stop (le script ne s'arrête pas, il est en attente).
Même comportement que les autres scripts, la numérotation en arrière plan s'effectue correctement, mais la boucle while part en boucle infini (cpu 100%).

Le read se met en attente au départ, ensuite ca part en sucette !

edit: chez toi ca ne part en boucle infini ???

Dernière modification par AnsuzPeorth (Le 04/05/2010, à 21:13)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#20 Le 04/05/2010, à 21:55

Totor

Re : read < FIFO Appel système interrompu

ben non, pas de boucle infinie !
edit : aurais-tu changé ton IFS ?

Dernière modification par Totor (Le 04/05/2010, à 22:02)


-- Lucid Lynx --

Hors ligne

#21 Le 04/05/2010, à 22:07

sputnick

Re : read < FIFO Appel système interrompu

Je soupçonne moi aussi un shell "fucké".

Ouvre en un autre au minimum, voir reboot pour écarter 100% de chances d'avoir "fucké" ton shell.


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#22 Le 05/05/2010, à 00:07

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Euuhhh, c'est vous qui avez des shells traffiqués smile

Par acquis de conscience, bien que j'avais déjà fait des tests hier, j'ai essayé sous lucid en live, donc bash d'origine, et les différents scripts ont le même fonctionnement que sous hardy, ca boucle ...!

Si chez vous ca boucle pas ....??? (je voudrai pas vous faire un affront, mais vous avez posé un echo dans la boucle while, peut être que vos ordis sont tellement puissant qu'une boucle infini ne se fait pas remarquée ... Ca m'étonnerais qd même !)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#23 Le 05/05/2010, à 00:33

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Bon après qqles essais, finalement ma solution de boucle imbriquées fonctionne nickel, un petit time.sleep(0.0001) suffit pour empêcher les bugs (comme limite de temps de réactions ca suffira  smile).

Par contre c'est vraiment étrange cette histoire de script qui fonctionne chez vous et pas chez moi ... !

Je vais pouvoir avancer, bien que ces semaines ci j'aurais pas trop de temps.

Merci !

Dernière modification par AnsuzPeorth (Le 05/05/2010, à 00:34)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#24 Le 05/05/2010, à 10:03

Totor

Re : read < FIFO Appel système interrompu

AnsuzPeorth a écrit :

Euuhhh, c'est vous qui avez des shells traffiqués smile

Nop, install toute fraiche de lundi

AnsuzPeorth a écrit :

Si chez vous ca boucle pas ....??? (je voudrai pas vous faire un affront, mais vous avez posé un echo dans la boucle while, peut être que vos ordis sont tellement puissant qu'une boucle infini ne se fait pas remarquée ... Ca m'étonnerais qd même !)

Non, ça ne boucle pas. C'est d'ailleurs pour cela que j'ai précisé que mon read bloque jusqu'à ce qu'il y ait quelque dans le pipe.
Et oui, c'est ce que j'ai fait à la lecture de ceci :

AnsuzPeorth a écrit :

@Totor
Chez moi tous ces exemples fonctionne, mais ils tournent en boucle infini (j'ai placé un echo, et il suffit de voir les ressources CPU).

Dernière modification par Totor (Le 05/05/2010, à 10:06)


-- Lucid Lynx --

Hors ligne

#25 Le 05/05/2010, à 17:56

AnsuzPeorth

Re : read < FIFO Appel système interrompu

Etrange ....!
Si ca vient pas des scripts ni de la version de bash, ca doit venir de plus haut ....!
Il y aurait un lock au niveau du processeur ? Jamais entendu parlé de ça !

Y a pas de raisons, pour toi une installe fraiche de lucid, pour moi en live lucid et pas le même résultat .... moi pas comprendre !

PROC: pentium HT 3.00 Ghz

Dernière modification par AnsuzPeorth (Le 05/05/2010, à 17:57)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne