j'ai un fichier correspondant à une liste de tache à faire.
Certaines peuvent prendre un temps indeterminé (long); je souhaite
arrêter ce traitement au bout d'un certain temps.
Le script original est le suivant:
_job()
{ (des trucs..) }
for tache in `cat liste_tache`
do
echo la tache $tache est lancée
_job $tache
done
Maintenant, je souhait forcer un timeout de 5s par tache (le timeout
est à la louche, la précision temporelle n'est pas recherchée). Je
cherche juste à éviter certains timeout monstrueux. En gros, soit la
tache réussit en moins de 1 à 2s, soit elle est bloquée pour plusieurs
minutes; de plus tuer la tache est sans conséquence dans mon cas.
J'ai donc écrit:
for tache in `cat liste_tache`
do
echo la tache $tache est lancée
_job $tache & job_pid=$!
( sleep 5; echo la tache $tache a un PB ; kill $job_pid ) & ruler_pid=$!
wait $job_pid
kill $ruler_pid
done
J'ai deux questions:
1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau rediriger
la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours
le message de kill m'indiquant que le process est tué). Comment afficher
une sortie propre?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Cyrille Lefevre
Kevin Denis a écrit :
J'ai donc écrit: for tache in `cat liste_tache` do echo la tache $tache est lancée _job $tache & job_pid=$! ( sleep 5; echo la tache $tache a un PB ; kill $job_pid ) & ruler_pid= $! wait $job_pid kill $ruler_pid done
J'ai deux questions: 1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau red iriger la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours le message de kill m'indiquant que le process est tué). Comment affic her une sortie propre?
2/ Est-ce correct ou bien y a t'il plus propre?
Merci
Bonjour,
je suppose que tu es sous bash ? mauvais shell, changer shell...
cela semble correcte hormis la boucle for, j'ai toujours une préférence pour les boucles while dans ce cas :
while read -r REPLY; do ... done < liste_tache
ce qui évite, par ailleurs, un fork inutile :-)
PS : normalement, il n'est pas nécessaire de spécifier un paramètre à read, dans ce cas il est supposé remplir la variable REPLY. pour autant, je suis tombé sur un cas, en bash, ou REPLY n'était pas correctement rempli (ou vidé s'il n'y a rien à lire, je ne sais plus)...
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
Kevin Denis a écrit :
J'ai donc écrit:
for tache in `cat liste_tache`
do
echo la tache $tache est lancée
_job $tache & job_pid=$!
( sleep 5; echo la tache $tache a un PB ; kill $job_pid ) & ruler_pid= $!
wait $job_pid
kill $ruler_pid
done
J'ai deux questions:
1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau red iriger
la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours
le message de kill m'indiquant que le process est tué). Comment affic her
une sortie propre?
2/ Est-ce correct ou bien y a t'il plus propre?
Merci
Bonjour,
je suppose que tu es sous bash ?
mauvais shell, changer shell...
cela semble correcte hormis la boucle for, j'ai toujours
une préférence pour les boucles while dans ce cas :
while read -r REPLY; do
...
done < liste_tache
ce qui évite, par ailleurs, un fork inutile :-)
PS : normalement, il n'est pas nécessaire de spécifier un
paramètre à read, dans ce cas il est supposé remplir la
variable REPLY. pour autant, je suis tombé sur un cas, en
bash, ou REPLY n'était pas correctement rempli (ou vidé
s'il n'y a rien à lire, je ne sais plus)...
Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
J'ai donc écrit: for tache in `cat liste_tache` do echo la tache $tache est lancée _job $tache & job_pid=$! ( sleep 5; echo la tache $tache a un PB ; kill $job_pid ) & ruler_pid= $! wait $job_pid kill $ruler_pid done
J'ai deux questions: 1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau red iriger la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours le message de kill m'indiquant que le process est tué). Comment affic her une sortie propre?
2/ Est-ce correct ou bien y a t'il plus propre?
Merci
Bonjour,
je suppose que tu es sous bash ? mauvais shell, changer shell...
cela semble correcte hormis la boucle for, j'ai toujours une préférence pour les boucles while dans ce cas :
while read -r REPLY; do ... done < liste_tache
ce qui évite, par ailleurs, un fork inutile :-)
PS : normalement, il n'est pas nécessaire de spécifier un paramètre à read, dans ce cas il est supposé remplir la variable REPLY. pour autant, je suis tombé sur un cas, en bash, ou REPLY n'était pas correctement rempli (ou vidé s'il n'y a rien à lire, je ne sais plus)...
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
Kevin Denis
Le 20-05-2009, Cyrille Lefevre a écrit :
J'ai deux questions: 1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau rediriger la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours le message de kill m'indiquant que le process est tué). Comment afficher une sortie propre?
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type Etc..
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script mais un output du shell qui lance le script. Ainsi lancer le script: script > resultat (...) cat resultat
donne un resultat propre (ie, sans les messages kill)
La solution consiste donc à lancer un sous-shell qui va lui, tout envoyer vers /dev/null, évitant de pourrir ma sortie standard. Le problème, c'est que dans ce sous shell, un echo "..." n'est pas affiché. J'ai du donc employer une fonction, et un fichier temporaire:
_func_do() { #clean_up [ -f result ] && rm result touch working for tache in `cat liste_tache` do echo $tache " en cours" >> result _job $tache & tache_pid=$! ( sleep 3; kill $tache_pid ; echo PB $tache >> result ) & ruler_pid=$! wait $tache_pid kill $ruler_pid done #job done, on supprime le fichier working rm working }
#on lance cette fonction en tache de fond en renvoyant tout vers #le /dev/null ( exec 9>&2 2> /dev/null touch working _func_do > /dev/null exec 2>&9 9>&- ) &
#On affiche à l'écran ce qui se passe while [ -f working ] do [ -f result ] && cat result [ -f result ] && rm result sleep 1 done [ -f result ] && cat result [ -f result ] && rm result
while read -r REPLY; do ... done < liste_tache ce qui évite, par ailleurs, un fork inutile :-)
Certes, le for était déjà présent, en fait. Je travaille à une amélioration de script. L'idée, c'est qu'en connaissant le nombre de tache, on soit capable d'estimer la limite haute du temps nécessaire à les réaliser. Je ne pensais pas que ce soit si tordu de mettre un timer, en conservant une sortie lisible. Il n'existe pas de fonction shell 'toute intégrée' ? Genre: timer -n 15s job qui défnirait un max de 15s pour lancer et terminer une tache?
PS : normalement, il n'est pas nécessaire de spécifier un paramètre à read, dans ce cas il est supposé remplir la variable REPLY. pour autant, je suis tombé sur un cas, en bash, ou REPLY n'était pas correctement rempli (ou vidé s'il n'y a rien à lire, je ne sais plus)...
Ok, je vais voir. Je pense toutefois que je peux améliorer encore un peu ce système, comme par exemple mettre une FIFO à la place d'un fichier temporaire 'result' pour afficher la sortie. -- Kevin
Le 20-05-2009, Cyrille Lefevre a écrit :
J'ai deux questions:
1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau rediriger
la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours
le message de kill m'indiquant que le process est tué). Comment afficher
une sortie propre?
Toujours pas. La sortie est toujours parasitée par les messages
line 15: 8871 Complété job -q $tache
line 16: kill: (8872) - Aucun processus de ce type
Etc..
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script
mais un output du shell qui lance le script. Ainsi lancer le script:
script > resultat
(...)
cat resultat
donne un resultat propre (ie, sans les messages kill)
La solution consiste donc à lancer un sous-shell qui va lui, tout
envoyer vers /dev/null, évitant de pourrir ma sortie standard.
Le problème, c'est que dans ce sous shell, un echo "..." n'est
pas affiché. J'ai du donc employer une fonction, et un fichier
temporaire:
_func_do()
{
#clean_up
[ -f result ] && rm result
touch working
for tache in `cat liste_tache`
do
echo $tache " en cours" >> result
_job $tache & tache_pid=$!
( sleep 3; kill $tache_pid ; echo PB $tache >> result ) & ruler_pid=$!
wait $tache_pid
kill $ruler_pid
done
#job done, on supprime le fichier working
rm working
}
#on lance cette fonction en tache de fond en renvoyant tout vers
#le /dev/null
( exec 9>&2 2> /dev/null
touch working
_func_do > /dev/null
exec 2>&9 9>&- ) &
#On affiche à l'écran ce qui se passe
while [ -f working ]
do
[ -f result ] && cat result
[ -f result ] && rm result
sleep 1
done
[ -f result ] && cat result
[ -f result ] && rm result
while read -r REPLY; do
...
done < liste_tache
ce qui évite, par ailleurs, un fork inutile :-)
Certes, le for était déjà présent, en fait. Je travaille à une
amélioration de script. L'idée, c'est qu'en connaissant le nombre de
tache, on soit capable d'estimer la limite haute du temps nécessaire à
les réaliser.
Je ne pensais pas que ce soit si tordu de mettre un timer,
en conservant une sortie lisible. Il n'existe pas de fonction shell
'toute intégrée' ? Genre:
timer -n 15s job
qui défnirait un max de 15s pour lancer et terminer une tache?
PS : normalement, il n'est pas nécessaire de spécifier un
paramètre à read, dans ce cas il est supposé remplir la
variable REPLY. pour autant, je suis tombé sur un cas, en
bash, ou REPLY n'était pas correctement rempli (ou vidé
s'il n'y a rien à lire, je ne sais plus)...
Ok, je vais voir. Je pense toutefois que je peux améliorer encore
un peu ce système, comme par exemple mettre une FIFO à la place
d'un fichier temporaire 'result' pour afficher la sortie.
--
Kevin
J'ai deux questions: 1/ Ma sortie est parasitée par tous les kill envoyés (j'ai beau rediriger la sortie standard ou la sortie d'erreur vers /dev/null, j'ai toujours le message de kill m'indiquant que le process est tué). Comment afficher une sortie propre?
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type Etc..
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script mais un output du shell qui lance le script. Ainsi lancer le script: script > resultat (...) cat resultat
donne un resultat propre (ie, sans les messages kill)
La solution consiste donc à lancer un sous-shell qui va lui, tout envoyer vers /dev/null, évitant de pourrir ma sortie standard. Le problème, c'est que dans ce sous shell, un echo "..." n'est pas affiché. J'ai du donc employer une fonction, et un fichier temporaire:
_func_do() { #clean_up [ -f result ] && rm result touch working for tache in `cat liste_tache` do echo $tache " en cours" >> result _job $tache & tache_pid=$! ( sleep 3; kill $tache_pid ; echo PB $tache >> result ) & ruler_pid=$! wait $tache_pid kill $ruler_pid done #job done, on supprime le fichier working rm working }
#on lance cette fonction en tache de fond en renvoyant tout vers #le /dev/null ( exec 9>&2 2> /dev/null touch working _func_do > /dev/null exec 2>&9 9>&- ) &
#On affiche à l'écran ce qui se passe while [ -f working ] do [ -f result ] && cat result [ -f result ] && rm result sleep 1 done [ -f result ] && cat result [ -f result ] && rm result
while read -r REPLY; do ... done < liste_tache ce qui évite, par ailleurs, un fork inutile :-)
Certes, le for était déjà présent, en fait. Je travaille à une amélioration de script. L'idée, c'est qu'en connaissant le nombre de tache, on soit capable d'estimer la limite haute du temps nécessaire à les réaliser. Je ne pensais pas que ce soit si tordu de mettre un timer, en conservant une sortie lisible. Il n'existe pas de fonction shell 'toute intégrée' ? Genre: timer -n 15s job qui défnirait un max de 15s pour lancer et terminer une tache?
PS : normalement, il n'est pas nécessaire de spécifier un paramètre à read, dans ce cas il est supposé remplir la variable REPLY. pour autant, je suis tombé sur un cas, en bash, ou REPLY n'était pas correctement rempli (ou vidé s'il n'y a rien à lire, je ne sais plus)...
Ok, je vais voir. Je pense toutefois que je peux améliorer encore un peu ce système, comme par exemple mettre une FIFO à la place d'un fichier temporaire 'result' pour afficher la sortie. -- Kevin
tiens, ça marche d'habitude ! je retesterai à l'occasion, mais je sais que j'utilise ce subterfuge dans des scripts existants et en prod...
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script mais un output du shell qui lance le script. Ainsi lancer le script: script > resultat (...) cat resultat
donne un resultat propre (ie, sans les messages kill)
duplique stdout et envoie tes messages dedans, cf plus bas.
[snip]
#on lance cette fonction en tache de fond en renvoyant tout vers #le /dev/null ( exec 9>&2 2> /dev/null touch working _func_do > /dev/null exec 2>&9 9>&- ) &
( echo to devnull echo >&8 to stdout echo >&9 to stderr ) 8>&1 9>&2 > /dev/null 2>&1
[snip]
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
tiens, ça marche d'habitude ! je retesterai à l'occasion, mais je sais
que j'utilise ce subterfuge dans des scripts existants et en prod...
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script
mais un output du shell qui lance le script. Ainsi lancer le script:
script > resultat
(...)
cat resultat
donne un resultat propre (ie, sans les messages kill)
duplique stdout et envoie tes messages dedans, cf plus bas.
[snip]
#on lance cette fonction en tache de fond en renvoyant tout vers
#le /dev/null
( exec 9>&2 2> /dev/null
touch working
_func_do > /dev/null
exec 2>&9 9>&- ) &
(
echo to devnull
echo >&8 to stdout
echo >&9 to stderr
) 8>&1 9>&2 > /dev/null 2>&1
[snip]
Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
tiens, ça marche d'habitude ! je retesterai à l'occasion, mais je sais que j'utilise ce subterfuge dans des scripts existants et en prod...
Mais j'ai compris pourquoi. En fait ce n'est pas un output du script mais un output du shell qui lance le script. Ainsi lancer le script: script > resultat (...) cat resultat
donne un resultat propre (ie, sans les messages kill)
duplique stdout et envoie tes messages dedans, cf plus bas.
[snip]
#on lance cette fonction en tache de fond en renvoyant tout vers #le /dev/null ( exec 9>&2 2> /dev/null touch working _func_do > /dev/null exec 2>&9 9>&- ) &
( echo to devnull echo >&8 to stdout echo >&9 to stderr ) 8>&1 9>&2 > /dev/null 2>&1
[snip]
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
Lucas Levrel
Le 20 mai 2009, Kevin Denis a écrit :
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) : ( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Et pour le wait, pourquoi pas : wait $job_pid &>/dev/null ? J'ai fait un test avec un sleep comme tâche, ça marche...
-- LL
Le 20 mai 2009, Kevin Denis a écrit :
Toujours pas. La sortie est toujours parasitée par les messages
line 15: 8871 Complété job -q $tache
line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une
grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) :
( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Et pour le wait, pourquoi pas :
wait $job_pid &>/dev/null
? J'ai fait un test avec un sleep comme tâche, ça marche...
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) : ( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Et pour le wait, pourquoi pas : wait $job_pid &>/dev/null ? J'ai fait un test avec un sleep comme tâche, ça marche...
-- LL
Kevin Denis
Le 20-05-2009, Lucas Levrel a écrit :
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) : ( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Ok.
Et pour le wait, pourquoi pas : wait $job_pid &>/dev/null ? J'ai fait un test avec un sleep comme tâche, ça marche...
C'est curieux. Mais comme la solution donnée plus haut fonctionne bien, je vais laisser tel quel :) -- Kevin
Le 20-05-2009, Lucas Levrel <lucas.levrel@univ-paris12.fr> a écrit :
Toujours pas. La sortie est toujours parasitée par les messages
line 15: 8871 Complété job -q $tache
line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une
grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) :
( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Ok.
Et pour le wait, pourquoi pas :
wait $job_pid &>/dev/null
? J'ai fait un test avec un sleep comme tâche, ça marche...
C'est curieux. Mais comme la solution donnée plus haut fonctionne bien,
je vais laisser tel quel :)
--
Kevin
Toujours pas. La sortie est toujours parasitée par les messages line 15: 8871 Complété job -q $tache line 16: kill: (8872) - Aucun processus de ce type
Je ne suis pas un expert, donc attention, ce qui suit est peut-être une grosse connerie :-p
Déjà, l'erreur sur le deuxième kill est facile à enlever (grosse ruse !) : ( sleep 5s ; echo blabla ; kill $job_pid ; sleep 1s ) &
Ok.
Et pour le wait, pourquoi pas : wait $job_pid &>/dev/null ? J'ai fait un test avec un sleep comme tâche, ça marche...
C'est curieux. Mais comme la solution donnée plus haut fonctionne bien, je vais laisser tel quel :) -- Kevin
Kevin Denis
Le 20-05-2009, Cyrille Lefevre a écrit :
La solution consiste donc à lancer un sous-shell qui va lui, tout envoyer vers /dev/null, évitant de pourrir ma sortie standard. Le problème, c'est que dans ce sous shell, un echo "..." n'est pas affiché. J'ai du donc employer une fonction, et un fichier temporaire:
duplique stdout et envoie tes messages dedans, cf plus bas.
Finalement, un fifo est très pratique. Je crée le fifo, je dumpe tout dans /dev/null sauf certains messages que je peux envoyer dans ce fifo. Ensuite, une boucle lit ce fifo et affiche en temps réél ce qui se passe.
Merci -- Kevin
Le 20-05-2009, Cyrille Lefevre a écrit :
La solution consiste donc à lancer un sous-shell qui va lui, tout
envoyer vers /dev/null, évitant de pourrir ma sortie standard.
Le problème, c'est que dans ce sous shell, un echo "..." n'est
pas affiché. J'ai du donc employer une fonction, et un fichier
temporaire:
duplique stdout et envoie tes messages dedans, cf plus bas.
Finalement, un fifo est très pratique. Je crée le fifo, je dumpe
tout dans /dev/null sauf certains messages que je peux envoyer dans
ce fifo.
Ensuite, une boucle lit ce fifo et affiche en temps réél ce qui se
passe.
La solution consiste donc à lancer un sous-shell qui va lui, tout envoyer vers /dev/null, évitant de pourrir ma sortie standard. Le problème, c'est que dans ce sous shell, un echo "..." n'est pas affiché. J'ai du donc employer une fonction, et un fichier temporaire:
duplique stdout et envoie tes messages dedans, cf plus bas.
Finalement, un fifo est très pratique. Je crée le fifo, je dumpe tout dans /dev/null sauf certains messages que je peux envoyer dans ce fifo. Ensuite, une boucle lit ce fifo et affiche en temps réél ce qui se passe.