Comment exécuter une commande en arrière-plan avec un délai?

33

Quelqu'un peut-il me montrer comment créer un programme pour réaliser cette action: après 5 minutes

echo "80" > /sys/class/leds/blue/brightness

Je veux que ce programme soit exécuté en tâche de fond (comme un rngdservice). Je ne peux pas le faire car je ne connais pas beaucoup Linux.

utilisateur53337
la source

Réponses:

51
( sleep 300 ; echo "80" > /sys/class/leds/blue/brightness ) &

Ainsi, votre script continue ou vous restaurez le contrôle immédiatement, tandis qu'une nouvelle tâche en arrière-plan du script démarre, avec deux commandes: sommeil et écho.

L'erreur commune est d'essayer de donner à l'un sleepou l' autre echoou aux deux ce &qui ne fonctionnera pas comme prévu. Lancer une série de commandes ()bien que les génère dans un processus shell séparé, que vous pouvez ensuite envoyer en entier en arrière-plan &.


À cet esprit, où je l'ai trouvé activement utile. Dans un appareil intégré, je développe l'application principale qui fonctionne avec un chien de garde. Si cela échoue de manière à déclencher la réinitialisation du chien de garde peu de temps après le démarrage, il est difficile de le réparer à distance car le délai entre le démarrage du système d'exploitation et la réinitialisation est assez court, pas assez pour ssh et bloquer le démarrage de l'application. Il me faut donc un moyen de déterminer si le système a redémarré si rapidement et d'introduire un délai si c'est le cas, afin de me donner le temps de le réparer manuellement.

 [ -f /tmp/startdelay ] && sleep 30
 touch /tmp/startdelay
 ( sleep 30 ; rm /tmp/startdelay ) &
 [ -f /tmp/noautostart ] && exit 0
 start_app

Si je me connecte et que touch /tmp/noautostartl'application principale ne démarre pas. Si le chien de garde se déclenche, rm /tmp/startdelayil ne sera pas exécuté et la prochaine fois que le système démarrera, il me donnera 30 secondes supplémentaires pour l'arrêter. Sinon, le redémarrage sera rapide, sans délai.

SF.
la source
Oui, je suis d'accord, mais cela peut aussi faire partie de la réflexion de l'utilisateur ;-)
Kiwy
Les autres réponses semblent manquer la partie "en arrière-plan". Non, j'ai été assez explicite à ce sujet: /
goldilocks
@goldilocks: Vous avez ajouté l'envoi dans la partie arrière-plan uniquement après que j'ai posté ma réponse.
SF.
Non, ma réponse initiale était d'exécuter une fonction contenant sommeil avec &pour arrière plan de dormir; "il faut aussi que vous dormiez dans le sommeil" était dans la première ligne depuis le début. Si vous ne me croyez pas, regardez l'historique d'édition. Et ma réponse a 5 minutes de plus que la vôtre: P
goldilocks
1
@gekannt: ... euh, la question est "Comment exécuter une commande en arrière-plan avec un délai?" - Comment y arriverais-tu autrement? (Et non, si vous n’aurez pas l’arrière-plan du ()groupe, le shell original s’arrêtera jusqu’à ce que celui qui est apparu se termine.)
SF.
11

utiliser la atcommande

echo "echo \"80\" > /sys/class/leds/blue/brightness" | at now + 5 min

cela fonctionnera en arrière-plan

exussum
la source
2
C’est la bonne façon de procéder, mais le démon atd doit être exécuté et un paquet doit être installé sur la plupart des systèmes.
Julian
Vous pouvez utiliser des guillemets simples pour éviter les echofuites et renoncer complètement à l'aide d'un heredoc ou herestring.
Chris Down
@ Julian, atest une commande POSIX standard. Quel système de type Unix ne l'a pas disponible par défaut?
Stéphane Chazelas
1
@ StéphaneChazelas - bonne question. Je sais que j'ai eu ce problème, mais c'était il y a un moment. J'ai fait un peu de vérification et la commande at semble assez omniprésente. De plus, il semble que atd soit spécifique à Linux et même sur certains systèmes Linux, il pourrait être remplacé par un démon cron de style BSD. Considérons mon commentaire obsolète.
Julian
J'ai essayé 'à' et aucune commande n'a été trouvée sur Android 8
beppe9000
6

Si vous voulez que quelque chose s'exécute en 5 minutes, mais que le reste de votre programme continue (ou finisse), vous devez également mettre en veille le sommeil:

#!/bin/bash

runWithDelay () {
    sleep $1;
    shift;
    "${@}";
}

runWithDelay 3 echo world &
echo hello    

Cela imprimera helloet ensuite 3 secondes plus tard (après que le programme principal soit terminé), imprimez world.

La partie importante est &de transférer l'exécution de la fonction en arrière-plan.

boucle d'or
la source
1
Puis-je suggérer à la runWithDelay () { sleep $1; "${@:2}"; }place?
manatwork
1
Je pense que cela devrait se lire doWhateverWithDelay 3 &dans votre deuxième exemple.
Baarn
@manatwork: à la vôtre.
goldilocks
1
@goldilocks, l’essentiel dans l’utilisation $@est que vous puissiez le citer et qu’il soit étendu en tant que liste de mots cités. Donc mieux le faire "$@"(ou "${@}"si vous aimez les accolades). Voir pastebin.com/MU7hbB2C
manatwork
@manatwork: Remarque prise;) J'ai essayé d'utiliser args avec echo ( -n), mais c'était un peu naïf.
goldilocks