web-dev-qa-db-fra.com

Shell: est-il possible de retarder une commande sans utiliser `sleep`?

Existe-t-il des substituts, des alternatives ou des astuces bash pour retarder les commandes sans utiliser sleep? Par exemple, exécuter la commande ci-dessous sans utiliser réellement sleep:

$ sleep 10 && echo "This is a test"
22
user321697

Vous avez des alternatives à sleep: Ce sont at et cron. Contrairement à sleep, vous devez fournir l'heure à laquelle vous en avez besoin pour s'exécuter.

  • Assurez-vous que le service atd est en cours d'exécution en exécutant service atd status.
    Supposons maintenant que la date soit 11 h 17 UTC; si vous devez exécuter une commande à 11:25 UTC, la syntaxe est: echo "This is a test" | at 11:25.
    Gardez maintenant à l'esprit que atd par défaut ne consignera pas la fin des travaux. Pour plus d'informations, reportez-vous à cette lien . Il est préférable que votre application dispose de sa propre journalisation.

  • Vous pouvez planifier des travaux dans cron, pour plus d'informations: man cron pour voir ses options ou crontab -e pour ajouter de nouveaux emplois. /var/log/cron peut être vérifié pour les informations sur l'exécution des travaux.

FYI sleep system call suspend l'exécution en cours et la planifie w.r.t. l'argument lui a été transmis.

MODIFIER:

Comme l'a mentionné @Gaius, vous pouvez également ajouter des minutes à la commande at. Mais disons que l'heure est 12:30:30 et maintenant vous avez exécuté le planificateur avec now +1 minutes. Même si 1 minute, soit 60 secondes, a été spécifiée, le at n'attend pas vraiment 12:31:30 pour exécuter le travail, il exécute plutôt le travail à 12:31:00. Les unités de temps peuvent être minutes, hours, days, or weeks. Pour plus d'informations, reportez-vous man at

par exemple: echo "ls" | at now +1 minutes

18
ss_iwe

Avec bash builtins, vous pouvez faire:

coproc read -t 10 && wait "$!" || true

Pour dormir pendant 10 secondes sans utiliser sleep. Le coproc doit faire en sorte que le stdin de read soit un tube d'où rien ne sortira jamais. || true Est dû au fait que le statut de sortie de wait reflétera une livraison SIGALRM qui entraînerait la fermeture du shell si l'option errexit était définie.

Dans d'autres coquilles:

mksh et ksh93 ont sleep intégré, inutile d'utiliser autre chose là-bas (bien qu'ils prennent également en charge read -t).

zsh prend également en charge read -t, mais a également un wrapper intégré autour de select(), vous pouvez donc également utiliser:

zmodload zsh/zselect
zselect -t 1000 # centiseconds

Si vous voulez planifier l'exécution de choses à partir d'une session Shell interactive, consultez également le module zsh/sched Dans zsh .

29
Stéphane Chazelas

Quelques autres idées.

top -d10 -n2 >/dev/null

vmstat 10 2 >/dev/null

sar 10 1 >/dev/null

timeout 10s tail -f /dev/null
7
steve

Puisqu'il y a des réponses qui suggèrent d'utiliser le non standard -t delay option de read, voici un moyen de faire une lecture expirée dans un Shell standard:

{ ss=`stty -g`; stty -icanon min 0 time 20; read foo; stty "$ss"; }

L'argument de stty time est en dixièmes de seconde.

6
mosvy

Utilisation de la variable intégrée bash $SECONDS et une boucle occupée:

for((target=$((SECONDS + 10)); SECONDS < target; true)); do :; done
5
Jeff Schaller

l'astuce la plus ancienne du livre:

read && echo "This is a test"

Il suffit de frapper Enter et ça va continuer!

4
Fabby

À l'époque des micro-ordinateurs exécutant BASIC, les retards étaient généralement accomplis avec une boucle vide:

FOR I = 1 TO 10000:NEXT

Le même principe pourrait être utilisé pour insérer un retard dans un script Shell:

COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done

Bien sûr, le problème avec cette approche est que la longueur du retard variera d'une machine à l'autre en fonction de la vitesse de son processeur (ou même sur la même machine sous différentes charges). Contrairement à sleep, il maximisera probablement aussi votre CPU (ou l'un de ses cœurs).

4
Psychonaut

Un classique du pays des fenêtres et des lots:

ping -c 11 localhost >/dev/null && echo "This is a test"
3
Joker_vD

Il n'y a pas de fonction intégrée, qui fait la même chose que sleep (sauf si sleep est intégré). Cependant, il existe d'autres commandes qui attendent.

Quelques-uns incluent.

  • at et cron: utilisés pour planifier des tâches à un moment précis.

  • inotifywait: utilisé pour attendre un fichier ou des fichiers à modifier/supprimer/ajouter/etc

3
ctrl-alt-delor

Si vous voulez attendre interactivement une nouvelle ligne dans un fichier, alors

tail -f

En attente d'une modification sur un système de fichiers? Ensuite, utilisez par exemple.

inotify / inoticoming

Et il existe d'autres options, selon ce que vous entendez par "attendre".

0
Edheldil