Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

(bash:débutant) exécuter une commande une durée déterminée

10 réponses
Avatar
alouest.du.soleil
Bonjour à tous,

Je souhaite enregistrer en mon absence mon émission radio préférée, émise en
streaming mp3. J'utilise dans un script wget qui sauvegarde le streaming en
question, mais il faut l'interrompre au terme de la durée de l'émission.
J'essaye ceci :

TODAY=$(date +%x-%X)
URL="http://stream1.rtbf.be:8000/lapremiere"
LENGTH=45m

wget -q -O "$TODAY.mp3" $URL &
PROCESS_NUM=$(ps -x | grep $TODAY | cut -b 1-6 )
sleep $LENGTH
kill $PROCESS_NUM

Mais je me dis que ça n'est pas satisfaisant, parce que l'identité du processus
repose sur la présence d'une chaîne de caractère, et que je récupère
inévitablement 2 numéros de processus parce que la commande "grep " apparaît
elle-même dans la liste renvoyée par ps :-(

Je me demandais donc
- si vous voyez une manière de résoudre le double n° de processus
- si vous voyez une meilleure manière de gérer l'interruption de cette
commande, en l'incluant dans une boucle while par exemple.

Merci d'avance,
--
^^ Gauthier
(_____/°°-ç
| \_`-"
)/@mmm||
\nn \nn FOE-Belgium : http://www.amisdelaterre.be

10 réponses

Avatar
[Sauron De Mordor]
Gauthier wrote:

Bonjour à tous,

Je souhaite enregistrer en mon absence mon émission radio préféré e, émise en
streaming mp3. J'utilise dans un script wget qui sauvegarde le streamin g en
question, mais il faut l'interrompre au terme de la durée de l'émis sion.
J'essaye ceci :

TODAY=$(date +%x-%X)
URL="http://stream1.rtbf.be:8000/lapremiere"
LENGTHEm

wget -q -O "$TODAY.mp3" $URL &


PROCESS NUM=$!

PROCESS_NUM=$(ps -x | grep $TODAY | cut -b 1-6 )
sleep $LENGTH
kill $PROCESS_NUM


Mais je me dis que ça n'est pas satisfaisant, parce que l'identité du processus
repose sur la présence d'une chaîne de caractère, et que je réc upère
inévitablement 2 numéros de processus parce que la commande "grep " apparaît
elle-même dans la liste renvoyée par ps :-(

Je me demandais donc
- si vous voyez une manière de résoudre le double n° de processus
- si vous voyez une meilleure manière de gérer l'interruption de ce tte
commande, en l'incluant dans une boucle while par exemple.

Merci d'avance,


Avatar
Laurent Wacrenier
[Sauron De Mordor] écrit:


Gauthier wrote:

Bonjour à tous,

Je souhaite enregistrer en mon absence mon émission radio préférée, émise en
streaming mp3. J'utilise dans un script wget qui sauvegarde le streaming en
question, mais il faut l'interrompre au terme de la durée de l'émission.
J'essaye ceci :

TODAY=$(date +%x-%X)
URL="http://stream1.rtbf.be:8000/lapremiere"
LENGTHEm

wget -q -O "$TODAY.mp3" $URL &


PROCESS NUM=$!

PROCESS_NUM=$(ps -x | grep $TODAY | cut -b 1-6 )
sleep $LENGTH
kill $PROCESS_NUM




également :

(sleep ${LENGTH}; kill $$) &
exec wget ...


Avatar
Pascal Bourguignon
Laurent Wacrenier <lwa@ teaser . fr> writes:
également :

(sleep ${LENGTH}; kill $$) &
exec wget ...


C'est pas croyable les bétises qu'on peut lire parfois!

[ pascal]$ (sleep 1 ; echo $$ ) ; echo $$
18135
18135

[ pascal]$ (sleep 1 ; echo $$ ) & echo $$
[1] 18181
18135


Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!


--
__Pascal_Bourguignon__ http://www.informatimago.com/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Living free in Alaska or in Siberia, a grizzli's life expectancy is 35 years,
but no more than 8 years in captivity. http://www.theadvocates.org/

Avatar
alouest.du.soleil
Le 27 Nov 2003 23:13:39 +0100,
Pascal Bourguignon a écrit:

Laurent Wacrenier <lwa@ teaser . fr> writes:
également :

(sleep ${LENGTH}; kill $$) &
exec wget ...


C'est pas croyable les bétises qu'on peut lire parfois!


Ne nous énervons pas !!!


[ pascal]$ (sleep 1 ; echo $$ ) ; echo $$
18135
18135

[ pascal]$ (sleep 1 ; echo $$ ) & echo $$
[1] 18181
18135


Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!



Donc, si je comprends bien, c'est ; qu'il faut utiliser après la parenthèse.
Mais de toute façon, je ne comprend pas cette proposition ; j'aurais cru que
l'intérieur des parenthèses serait exécuté en premier, et ensuite seulement
ce qui suit (exec wget...)

Vous pouvez m'en dire plus ?
--
^^ Gauthier
(_____/°°-ç
| _`-"
)/@mmm||
nn nn FOE-Belgium : http://www.amisdelaterre.be


Avatar
Stephane Chazelas
2003-11-27, 23:13(+01), Pascal Bourguignon:

Laurent Wacrenier <lwa@ teaser . fr> writes:
également :

(sleep ${LENGTH}; kill $$) &
exec wget ...
[...]


Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!


$$ est le PID du shell qui a démarré le script, qu'on soit dans
un sous shell (en background, en foreground), dans un
arriere-arriere-arriere...-petit fils ou le processus père.

Elle est définie une fois pour toutes et n'est pas touchée par
la suite.

( ( ( ( echo $$ ) ) ) )
( ( echo $$ ) & ) &
echo $$
echo $$ >&2 | echo $$

Affichent tous la même chose.

Donc, le code de Laurent est correct $$ est le pid du shell qui
a lancé le script, ce sera aussi le pid de wget, puisqu'il y a
un exec.

Maintenant, que ce soit dans:

(sleep ${LENGTH}; kill $$) &
exec wget ...

ou

dans:
wget ... &
sleep $LENGTH
kill $!

il y a un risque (infime) qu'on tue le mauvais processus, si
wget s'est terminé et qu'un autre processus a réutilisé le même
PID entre temps.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]


Avatar
Stephane Chazelas
2003-11-27, 23:13(+01), Pascal Bourguignon:
[...]
[ pascal]$ (sleep 1 ; echo $$ ) ; echo $$
18135
18135

[ pascal]$ (sleep 1 ; echo $$ ) & echo $$
[1] 18181
18135

Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!
[...]


Au passage, ( ... ) implique un fork aussi. La différence avec
( ... ) &, c'est juste que le père fait un waitpid du fils.
Dans "/bin/echo $$", il y a un fork aussi.

Donc, pids différents aussi, mais dans un cas comme dans tout
autre, $$ ne bouge pas.

Pour connaître le pid du shell qui interprête une certaine
commande, on peut faire

pid=$(sh -c 'echo "$PPID"')
ou sous Linux:
{ read;read;read;read REPLY pid; } < /proc/self/status

Exemple:

{
pid=$(sh -c 'echo "$PPID"')
echo $$ $pid
(
pid=$(sh -c 'echo "$PPID"')
echo $$ $pid
)
(
pid=$(sh -c 'echo "$PPID"')
echo $$ $pid
) &
}

10333 10333
10333 10335
[1] 10337
10333 10337
[1]+ Done ( pid=$(sh -c 'echo "$PPID"'); echo $$ $pid )

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]

Avatar
Pascal Bourguignon
(Gauthier) writes:

Le 27 Nov 2003 23:13:39 +0100,
Pascal Bourguignon a écrit:

Laurent Wacrenier <lwa@ teaser . fr> writes:
également :

(sleep ${LENGTH}; kill $$) &
exec wget ...


C'est pas croyable les bétises qu'on peut lire parfois!


Ne nous énervons pas !!!


[ pascal]$ (sleep 1 ; echo $$ ) ; echo $$
18135
18135

[ pascal]$ (sleep 1 ; echo $$ ) & echo $$
[1] 18181
18135


Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!



Donc, si je comprends bien, c'est ; qu'il faut utiliser après la parenthèse.
Mais de toute façon, je ne comprend pas cette proposition ; j'aurais cru que
l'intérieur des parenthèses serait exécuté en premier, et ensuite seulement
ce qui suit (exec wget...)

Vous pouvez m'en dire plus ?


Oui, c'est moi qui ai écrit une grosse bétise. Désolé. Où c'est-y
qu'il vit l'enchanteur de Maupert déjà? J'ai coupé collé le résultat
de "(sleep 1 ; echo $$ ) & echo $$" un peu trop vite:

$ (sleep 1 ; echo $$ ) & echo $$
[3] 10096
2255
$ 2255


Dans un sous shell, $$ référence toujours le pid du shell initial. Alors:

(sleep ${LENGTH}; kill $$) & exec wget ...

devrait fonctionner.


--
__Pascal_Bourguignon__ http://www.informatimago.com/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Living free in Alaska or in Siberia, a grizzli's life expectancy is 35 years,
but no more than 8 years in captivity. http://www.theadvocates.org/



Avatar
Pascal Bourguignon
Stephane Chazelas writes:

2003-11-27, 23:13(+01), Pascal Bourguignon:
[...]
[ pascal]$ (sleep 1 ; echo $$ ) ; echo $$
18135
18135

[ pascal]$ (sleep 1 ; echo $$ ) & echo $$
[1] 18181
18135

Au cas où tu ne n'aurais pas remarqué, & <=> fork <=> on change de PID!
[...]


Au passage, ( ... ) implique un fork aussi. La différence avec
( ... ) &, c'est juste que le père fait un waitpid du fils.
Dans "/bin/echo $$", il y a un fork aussi.


Oui, mais c'est différent, $$ est un argument évalué par le shell
appelant. Sauf qu'il n'est initialisé que par le shell initial et pas
par les sous-shells. Je suis tombé dans ce piège.


Donc, pids différents aussi, mais dans un cas comme dans tout
autre, $$ ne bouge pas.

Pour connaître le pid du shell qui interprête une certaine
commande, on peut faire

pid=$(sh -c 'echo "$PPID"')
ou sous Linux:
{ read;read;read;read REPLY pid; } < /proc/self/status


Merci.

--
__Pascal_Bourguignon__ http://www.informatimago.com/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Living free in Alaska or in Siberia, a grizzli's life expectancy is 35 years,
but no more than 8 years in captivity. http://www.theadvocates.org/


Avatar
Ian
Gauthier wrote:

Bonjour à tous,

Je souhaite enregistrer en mon absence mon émission radio préférée, émise en
streaming mp3. J'utilise dans un script wget qui sauvegarde le streaming en
question, mais il faut l'interrompre au terme de la durée de l'émission.
J'essaye ceci :

TODAY=$(date +%x-%X)
URL="http://stream1.rtbf.be:8000/lapremiere"
LENGTHEm

wget -q -O "$TODAY.mp3" $URL &
PROCESS_NUM=$(ps -x | grep $TODAY | cut -b 1-6 )
sleep $LENGTH
kill $PROCESS_NUM

Mais je me dis que ça n'est pas satisfaisant, parce que l'identité du processus
repose sur la présence d'une chaîne de caractère, et que je récupère
inévitablement 2 numéros de processus parce que la commande "grep " apparaît
elle-même dans la liste renvoyée par ps :-(

Je me demandais donc
- si vous voyez une manière de résoudre le double n° de processus


En général, on ajoute un | grep -v grep dans la ligne de commande :

PROCESS_NUM=$(ps -x | grep $TODAY | grep -v grep | cut -b 1-6 )


est-ce ce que tu cherches à faire ?

Avatar
Stephane Chazelas
2003-12-03, 00:58(+01), Ian:
[...]
En général, on ajoute un | grep -v grep dans la ligne de commande :

PROCESS_NUM=$(ps -x | grep $TODAY | grep -v grep | cut -b 1-6 )
[...]


Bof, je dirais qu'en général, on utilise, fuser, lsof ou

ps -e -o pid=,args= | awk -v "t=$TODAY" '
index($0,t) && $2 != "awk" {print $1}'

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]