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

Tuer un script après une durée fixe

9 réponses
Avatar
steve
Salut,

Sur un Raspberry tournant sous raspbian, j'ai un script du genre

#!/bin/sh

raspivid [des option] | ffmpeg [d'autres options]


(raspivid permet de contrôler une caméra)

Le script tourne à l'infini (il permet de streamer une vidéo)

Je lance ce script via une tâche cron.

J'aimerais arrêter ce script après 30 minutes. Pour cela, j'ai trouvé la
commande timeout du paquet coreutils. J'ai donc modifié le script ainsi:

timeout 30m raspivid [des options] | ffmpeg [d'autres options]

En testant cette solution, je m'aperçois que la commande raspivid est
bien tuée après 30 minutes (j'ai pris des secondes pour mes tests), mais
pas la commande ffmpeg, qui est pipée. J'ai donc rajouté un autre
timeout devant ffmpeg comme ceci:

timeout 30m raspivid [des options] | timeout 30m ffmpeg [d'autres option]

Cette solution fait le job, mais je ne trouve pas très élégant
d'utiliser deux timeout. Ce serait mieux de tuer le script lui-même que
chaque commande à l'intérieur du script. Mais je ne vois pas comment
faire.

Idées, suggestions ?

Merci

S

9 réponses

Avatar
steve
Le 27-02-2018, à 11:18:02 +0100, Jean-Marc a écrit :
[...]
Idées, suggestions ?

timeout { mes_commandes; }

timeout: impossible d'exécuter la commande « { »: Aucun fichier ou dossier de ce type
Attention de bien terminer les commandes par des ";" et de laisser un
espace entre le dernier ";" et l'accolade fermante.

Ne marche pas, le script continue de tourner. J'ai essayé de mettre un
 ; juste avant le pipe, et ça ne marche pas non plus.
Avatar
daniel huhardeaux
Le 27/02/2018 à 10:21, steve a écrit :
Salut,

Bonjour
Sur un Raspberry tournant sous raspbian, j'ai un script du genre
#!/bin/sh
raspivid [des option] | ffmpeg [d'autres options]
(raspivid permet de contrôler une caméra)
Le script tourne à l'infini (il permet de streamer une vidéo)
Je lance ce script via une tâche cron.
J'aimerais arrêter ce script après 30 minutes. Pour cela, j'ai trouvé la
commande timeout du paquet coreutils. J'ai donc modifié le script ainsi:
timeout 30m raspivid [des options] | ffmpeg [d'autres options]
En testant cette solution, je m'aperçois que la commande raspivid est
bien tuée après 30 minutes (j'ai pris des secondes pour mes tests), mais
pas la commande ffmpeg, qui est pipée. J'ai donc rajouté un autre
timeout devant ffmpeg comme ceci:
timeout 30m raspivid [des options] | timeout 30m ffmpeg [d'autres option]
Cette solution fait le job, mais je ne trouve pas très élégant
d'utiliser deux timeout. Ce serait mieux de tuer le script lui-même que
chaque commande à l'intérieur du script. Mais je ne vois pas comment
faire.
Idées, suggestions ?

timeout 30 sh -c 'raspivid [des options] | ffmpeg [d'autres options]' ?
--
Daniel
Avatar
Jean-Marc
--Signature=_Tue__27_Feb_2018_14_17_46_+0100_t0OB_XEleDfPkCyA
Content-Type: text/plain; charset=UTF-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Tue, 27 Feb 2018 13:36:33 +0100
steve écrivait :
Le 27-02-2018, à 11:18:02 +0100, Jean-Marc a écrit :
[...]
Idées, suggestions ?

timeout { mes_commandes; }


apparemment, timeout ne prend comme paramètre qu'une commande, pas un bloc de commande.
Autre solution, démarrer un bash:
timeout bash -c " tes_commandes "
Les guillements sont importants, derrière le -c, bash s'attend à une chaîne de caractères qu'il interprètera comme étant des commandes.
Jean-Marc
--Signature=_Tue__27_Feb_2018_14_17_46_+0100_t0OB_XEleDfPkCyA
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEEWjgcRC0dCXkfm9hQHHLXC3pxPwFAlqVWnoACgkQQHHLXC3p
xPyliBAAk/oV+GfCtL5Xs34spwpISziTtb2ULdmwZMIuiYn/W78gnZtVGDAyrzYs
zY8AaSlm6VzXEZcDPxesdM5tIdLiuizDjL16zlR082tUhg097d962Uu72E3VQgB1
H2r6/dd06lPOxndAlhdcY5rWKnUKRB5gDJbPX5mAdcxIIl3NzSLLcLy7ZMU7BXZv
Xxtcni+mg0kCp9hBXrCLEsyMXPBAACEscamTgjEQ+5Ce5SLfb4Or6fk/t+O9T+SC
vWfgHXUjGpONTJ3DMEllSYrb051twM/djd5ggGiX07DibNQr+kCJMJ+I6z7kOTAr
uMlCbIiYfctzRikoNsjkB2sycSvC3od2ypOt69csd7hb5sXtbimXEYUnW+9sJixm
jJ01zMk3XEj0RHOzaFXLP1qV2WKM55V65iFtkAlopNIDIar4sRgdmNT1SXbboieh
rSv2AlAM0A7MZOAvcZUGctSaa0Uq/kr2eAleiOnzF6hsW5rnzkY9R8gW5HF83esq
4kSOhvWLKb834QAkDO/48Oyv7mslYIgPSGM/Sx0lq52efHlcVqzNhlDRYZXzxKJr
XgGNXTBFVUuykckTRmaNLQN/o/+7+58ciCAColShRcWiS/dKZCiu6jQUSslVso31
TzDMT2exzLYP6ZaLPfzJoBI7JaxLMlEc9YT5I2yjJXn5meAWJvU =mIiY
-----END PGP SIGNATURE-----
--Signature=_Tue__27_Feb_2018_14_17_46_+0100_t0OB_XEleDfPkCyA--
Avatar
Francois Lafont
Bonjour,
On 02/27/2018 10:21 AM, steve wrote:
J'aimerais arrêter ce script après 30 minutes. Pour cela, j'ai trouvé la
commande timeout du paquet coreutils. J'ai donc modifié le script ainsi:
timeout 30m raspivid [des options] | ffmpeg [d'autres options]
En testant cette solution, je m'aperçois que la commande raspivid est
bien tuée après 30 minutes (j'ai pris des secondes pour mes tests), mais
pas la commande ffmpeg, qui est pipée. J'ai donc rajouté un autre
timeout devant ffmpeg comme ceci:
timeout 30m raspivid [des options] | timeout 30m ffmpeg [d'autres option]
Cette solution fait le job, mais je ne trouve pas très élégant
d'utiliser deux timeout. Ce serait mieux de tuer le script lui-même que
chaque commande à l'intérieur du script. Mais je ne vois pas comment
faire.
Idées, suggestions ?

Je pense que tu devrais mettre le timeout sur la commande à droite
du pipe uniquement (ie ffmpeg). Normalement, la commande à gauche
du pipe (raspivid) devrait se stopper d'elle-même car elle recevra
le signal SIGPIPE.
--
François Lafont
Avatar
Vincent Lefevre
On 2018-02-27 14:24:35 +0100, Francois Lafont wrote:
Je pense que tu devrais mettre le timeout sur la commande à droite
du pipe uniquement (ie ffmpeg). Normalement, la commande à gauche
du pipe (raspivid) devrait se stopper d'elle-même car elle recevra
le signal SIGPIPE.

Mais seulement si elle écrit des données, au cas où elle ne le ferait
pas en permanence.
--
Vincent Lefèvre - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Avatar
Francois Lafont
On 02/27/2018 03:26 PM, Vincent Lefevre wrote:
Mais seulement si elle écrit des données, au cas où elle ne le ferait
pas en permanence.

Ah oui exact. Merci pour cette précision importante en effet.
--
François Lafont
Avatar
steve
Le 27-02-2018, à 14:24:35 +0100, Francois Lafont a écrit :
Idées, suggestions ?

Je pense que tu devrais mettre le timeout sur la commande à droite
du pipe uniquement (ie ffmpeg). Normalement, la commande à gauche
du pipe (raspivid) devrait se stopper d'elle-même car elle recevra
le signal SIGPIPE.

Et ça marche, hip hip hip hourra !
La bonne ligne est donc:
raspivid [options] | timeout -s KILL 15s ffmpeg [autres options]
(le -s KILL semble optionnel et inoffensif).
Pour répondre à Jean-Marc, la solution
timeout 15s bash -c " raspivid [options] | ffmpeg [autres options] "
tue bien raspivid, mais pas ffmpeg.
Merci à vous tous.
S
Avatar
steve
Salut,
Le 27-02-2018, à 14:48:14 +0100, yahoo a écrit :
Salut,
pour ma part j’exécute mes script avec systemd avec l'option RuntimeMaxSec
qui permet de définir un temps d’exécution du script avant de la tuer (et
mit en état d’échec).
Si cela peut être une solution ?

C'est en tout cas intéressant et je n'y avais pas du tout pensé. Il
faudrait pour cela écrire un fichier /etc/systemd/system/macamera.service
contenant quelque chose comme
[Unit]
Description=Mise en marche de la caméra
[Service]
Type=idle
ExecStart=$HOME/bin/script.sh
RuntimeMaxSec # en secondes
[Install]
WantedBy=multi-user.target
avec un fichier correspondant /etc/systemd/system/macamera.timer
[Unit]
Description=Heure de lancement
[Timer]
OnCalendar:00:00 # à 10h le matin
[Install]
WantedBy=timers.target
Est-ce qu'on peut mettre plusieurs OnCalendar à la suite ?
Je n'ai jamais écrit de tels fichiers, donc pas du tout sûr que ça soit
juste. Mais je vais essayer, ça va me permettre de mettre vraiment les
mains dans le système systemd.
Merci pour la suggestion et sur d'éventuelles autres sur l'écriture des
deux fichiers ci-dessus.
S
Avatar
Francois Lafont
Bonsoir,
On 02/27/2018 05:38 PM, steve wrote:
C'est en tout cas intéressant et je n'y avais pas du tout pensé. Il
faudrait pour cela écrire un fichier /etc/systemd/system/macamera.service
contenant quelque chose comme
[Unit]
Description=Mise en marche de la caméra
[Service]
Type=idle
ExecStart=$HOME/bin/script.sh
RuntimeMaxSec # en secondes
[Install]
WantedBy=multi-user.target
avec un fichier correspondant /etc/systemd/system/macamera.timer
[Unit]
Description=Heure de lancement
[Timer]
OnCalendar:00:00 # à 10h le matin
                   [Install]
WantedBy=timers.target

Faire du script un daemon me semble aussi une très bonne idée.
Et pour le coup, on peut sans doute dire beaucoup de choses sur
systemd, mais faire d'un petit script (qui ne forke pas) un
daemon est vraiment très simple.
Personnellement, je laisserais de côté les RuntimeMaxSec and
co pour faire au plus simple (ie un daemon qui doit être UP
H24) et je gérerais la plage d'exécution de la commande directement
dans le script shell avec un truc dans ce genre là (non testé hein) :
---%<-------%<-------%<-------%<-------%<-------%<---
#!/bin/sh
# Imaginons qu'on veuille que le « machin » tourne
# entre 17h30 et 18h30 (choix au pif).
start_time30
stop_time30
while true
do
# Petite pause de 30 secondes...
sleep 30
now=$(date +"%H%M")
# On teste si on a : 17h30 =< now < 18h30. Si c'est le cas, alors
# il faut lancer la commande.
if [ "$now" -ge "$start_time" ] && [ "$now" -lt "$stop_time" ]
then
delta=$((stop_time - now))
# Ici on met la commande qui-va-bien avec le timeout.
raspivid [options] | timeout -s KILL "${delta}m" ffmpeg [autres options]
fi
done
---%<-------%<-------%<-------%<-------%<-------%<---
À+
--
François Lafont