Il existe une commande Unix intégrée repeat
dont le premier argument est le nombre de répétitions d'une commande, la commande (avec tous les arguments) étant spécifiée par les arguments restants repeat
.
Par exemple,
% repeat 100 echo "I will not automate this punishment."
fera écho la chaîne donnée 100 fois puis s'arrêtera.
J'aimerais une commande similaire - appelons-la forever
- qui fonctionne de la même manière, sauf que le premier argument est le nombre de secondes de pause entre les répétitions et qu'il se répète indéfiniment. Par exemple,
% forever 5 echo "This will get echoed every 5 seconds forever and ever."
Je pensais demander si une telle chose existait avant de l'écrire. Je sais que c'est comme un script Perl ou Python à 2 lignes, mais il existe peut-être une méthode plus standard pour le faire. Si ce n'est pas le cas, n'hésitez pas à poster une solution dans votre langage de script préféré, à la manière de Rosetta Stone .
PS: Une meilleure façon de procéder serait peut-être de généraliser repeat
en prenant à la fois le nombre de répétitions (-1 signifiant l'infini) et le nombre de secondes de veille entre les répétitions. Les exemples ci-dessus deviendraient alors:
% repeat 100 0 echo "I will not automate this punishment."
% repeat -1 5 echo "This will get echoed every 5 seconds forever."
la source
type repeat
et laissez-moi savoir d'où vient?repeat
est une commande intégrée dans csh et tcsh.Réponses:
Essayez la
watch
commande.Pour que:
exécutera la commande toutes les secondes (enfin, techniquement, toutes les secondes plus le temps nécessaire
command
à l'exécution dewatch
(au moins, les implémentationsprocps
etbusybox
) dort une seconde entre deux exécutionscommand
), pour toujours.Souhaitez-vous passer la commande à la
exec
place desh -c
, utilisez l'-x
option:Sur macOS, vous pouvez obtenir
watch
des ports Mac :Ou vous pouvez l'obtenir de Homebrew :
la source
while true; do X; sleep Y; done
- C'est beaucoup mieux.cmdwatch
sur FreeBSD (depuis les ports:)sysutils/cmdwatch
.Frapper
while
+sleep
:Voici la même chose qu'un raccourci One-Liner (d'après les commentaires ci-dessous):
Utilise
;
pour séparer les commandes et utilisesleep 1
pour lewhile
test puisqu'il renvoie toujours true. Vous pouvez mettre plus de commandes dans la boucle - séparez-les simplement avec;
la source
sleep
n'y retournez pas toujours . Ī̲ a utilisé de telles boucles (bien qu'avec des délais plus longs), notamment parce qu'il existe un moyen de les terminer gracieusement en mettant fin au processus de sommeil.Ceci est juste une version abrégée d’autres
while+sleep
réponses, si vous exécutez ce type de tâches souvent comme votre routine quotidienne, vous évitez ainsi d’appuyer sur des touches inutiles et si votre ligne de commande commence à être plus longue, sachant que celle-ci est un peu plus facile. Mais celui-ci commence par dormir en premier.Ceci est généralement utile si vous devez suivre quelque chose qui a une sortie sur une ligne, telle que la charge de la machine:
la source
while clear; do date; command;sleep 5; done
while sleep
combinaison, enregistre les keystokes!Un problème que toutes les réponses postées jusqu'à présent ont, c'est que le temps d'exécution de la commande peut dériver. Par exemple, si vous faites une
sleep 10
commande entre deux et que la commande prend 2 secondes pour s'exécuter, elle s'exécutera toutes les 12 secondes. s'il faut un temps variable pour s'exécuter, le temps d'exécution peut être imprévisible à long terme.Cela pourrait être juste ce que vous voulez; si tel est le cas, utilisez l’une des autres solutions ou utilisez-la, mais simplifiez l’
sleep
appel.Pour une résolution d'une minute, les tâches cron seront exécutées à l'heure spécifiée, quelle que soit la durée de chaque commande. (En fait, un nouveau travail cron sera lancé même si le précédent est toujours en cours d'exécution.)
Voici un script Perl simple qui dort jusqu'à l'intervalle suivant. Ainsi, par exemple, avec un intervalle de 10 secondes, la commande peut s'exécuter à 12:34:00, 12:34:10, 12:34:20, etc., même si le La commande elle-même prend plusieurs secondes. Si la commande s'exécute plus de
interval
secondes, l'intervalle suivant sera ignoré (contrairement à cron). L'intervalle étant calculé par rapport à l'époque, un intervalle de 86 400 secondes (1 jour) sera exécuté à minuit UTC.la source
while :; do sleep 1m & command; wait; done
wait
ils les attendront tous). C'est réparable en changeantwait
àwait $!
, où$!
est le PID dusleep
processus. Postez ceci comme une réponse et je l’envois. Mais cela produit des sorties superflues dans un shell interactif.Je pense que toutes les réponses à ce jour sont soit trop compliquées, soit répondent à une question différente:
La vraie question était:
Ce sont deux choses très différentes lorsque la commande met du temps à se terminer.
Prenons par exemple le script
foo.sh
(supposons qu'il s'agit d'un programme qui prend quelques secondes à terminer).Vous souhaitez exécuter cela toutes les secondes, et la plupart suggèrent
watch -n1 ./foo.sh
, ouwhile sleep 1; do ./foo.sh; done
. Cependant, cela donne la sortie:Ce qui ne se fait pas exactement à chaque seconde. Même avec le
-p
drapeau, comme leman watch
suggère la page, le résultat est le même.Un moyen facile d'accomplir la tâche souhaitée, que certains abordent, consiste à exécuter la commande en arrière-plan. En d'autres termes:
Et c'est tout ce qu'il y a à faire.
Vous pouvez l'exécuter toutes les 500 ms avec
sleep 0.5
, ou ce que vous avez.la source
while :; do sleep 1 & ./foo.sh; wait; done
date +"%H:%M:%S.%N"
dans foo.sh pour voir comment la fraction augmentera lentement à chaque boucle.Dans
bash
:(
echo
pourrait être remplacé par n'importe quelle commande ...Ou dans
perl
:Où
print "I will not automate this punishment in absurdum.\n"
pourrait être remplacé par "toute" commande entourée de backticks (`).Et pour une pause, ajoutez une
sleep
déclaration dans la boucle for:et
la source
while [ 0 ]
est une mauvaise façon de l'écrire. Cela signifie0
est une chaîne de longueur> 0.while [ 1 ]
ouwhile [ jeff ]
ferait la même chose. Mieux vaut écrirewhile true
.while :
Recent bash> = 4.2 sous noyau récent, réponse basée.
Afin de limiter le temps d'exécution, il n'y a pas de fourches ! Seuls les éléments intégrés sont utilisés.
Pour cela,
read
j'utilise la fonction intégrée au lieu desleep
. Unfortunely cela ne fonctionnera pas avec Notty sessions.Fonction bash rapide "
repeat
" à la demande:Petit test avec des chaînes citées:
En fonction de la granularité et de la durée de la commande soumise ...
Dans les noyaux Linux récents, il existe un fichier procfile
/proc/timer_list
contenant des informations de temps en nanosecondes.Si vous voulez exécuter une commande exactement une fois par seconde, votre commande doit se terminer en moins d'une seconde! Et à partir de là, il
sleep
ne reste que le reste de la seconde actuelle.Si le délai est plus important et que votre commande ne nécessite pas beaucoup de temps, vous pouvez:
Mais si votre objectif est d’obtenir une granularité plus fine, vous devez:
Utilisez les informations en nanosecondes pour attendre le début d'une seconde ...
Pour cela, j'ai écrit une petite fonction bash:
Après les avoir achetés, vous pourriez:
exécuter
${command[@]}
directement en ligne de commande, que comparer àcela doit donner exactement le même résultat.
Engage la fonction bash "
repeat
" à la demande:Vous pourriez trouver ceci:
Alors essayez-le:
la source
read -t
est intégré , alors quesleep
non. Cela pourrait avoir un effet de bordure (c.-à-d. Que vous appuyez sur [touche: revenir] interrompre le sommeil tranquillement ), mais cela pourrait être traité par des tests$foo
Tu veux essayer ça (Bash)?
la source
repeat
est spécifique à csh et tcsh.Perl
la source
Bash et certains de ses shells apparentés ont la
(( ... ))
notation pratique dans laquelle les expressions arithmétiques peuvent être évaluées.Donc, pour répondre à votre troisième défi, où le nombre de répétitions et le délai entre chaque répétition doivent être configurables, voici une façon de le faire:
Cette réponse souffre également de la dérive de synchronisation couverte par la réponse de Keith .
la source
Comme mentionné par gbrandt, si la
watch
commande est disponible, utilisez-la. Cependant, certains systèmes Unix ne l’ont pas installé par défaut (du moins, ils ne le sont pas où je travaille).Voici une autre solution avec une syntaxe et une sortie légèrement différentes (fonctionne sous BASH et SH):
Edit: j'ai enlevé des "." dans la dernière déclaration d'écho ... le reste de mes jours Perl;)
la source
while [ 1 ]
ne fonctionne que parce que 1 est traité comme une chaîne, tout commewhile [ -n 1 ]
.while [ 0 ]
ouwhile [ jeff ]
ferait la même chose.while true
est beaucoup plus logique.Si votre intention n'est pas d'afficher un message sur votre écran et si vous pouviez vous permettre de répéter le travail en minutes, crontab serait peut-être votre meilleur outil. Par exemple, si vous souhaitez exécuter votre commande toutes les minutes, vous écrirez quelque chose comme ceci dans votre
crontab
fichier:S'il vous plaît consulter le tutoriel pour plus d'exemple. En outre, vous pouvez facilement définir les minutages à l’aide de Crontab Code Generator .
la source
Et si on avait les deux?
Voici l’idée: avec seulement "intervalle", cela se répète pour toujours. Avec "intervalle" et "fois", il répète ce nombre de fois, séparé par "intervalle".
L'usage :
Donc, l'algorithme sera:
Par conséquent :
la source
sleep
accepte.J'ai fini par créer une variante sur la réponse de swalog. Avec le sien, vous deviez attendre X secondes pour la première itération, je cours aussi au premier plan alors ..
la source
Rapide, sale et probablement dangereux pour démarrer, mais si vous êtes aventureux et savez ce que vous faites, mettez cela en
repeat.sh
etchmod 755
il,Invoquer avec
./repeat.sh <command> <interval>
Mon sens spidey dit que c'est probablement une façon perverse de faire cela. Mon sens spidey est-il correct?
la source
sleep $1; shift; "$@"
ou similaire serait beaucoup mieux.Vous pouvez exécuter un script à partir d'init (en ajoutant une ligne à / etc / inittab). Ce script doit exécuter votre commande, patientez pendant le temps que vous souhaitez attendre jusqu'à ce qu'il soit exécuté à nouveau et quittez-le. Init lancera votre script à nouveau après la sortie.
la source
Un moyen facile de répéter un travail à partir de crontab avec un intervalle inférieur à une minute (exemple de 20 secondes):
crontab: * * * * * script.sh
script.sh:
la source
Vous pouvez obtenir le pouvoir de l'interpréteur python de shell.
remplacez-en cinq en tout temps (sec) que vous aimez.
Attention: le retour utilise SHIFT + ENTER pour renvoyer une entrée en shell. Et n'oubliez pas de taper 4 SPACE indent dans chaque ligne de la boucle while.
la source
python
l »os.system()
exécute un shell pour interpréter la ligne de commande, afin d' invoquerpython
pour lancer des obus dans une boucle pour exécuter une commande est périodiquement un peu exagéré. Vous pourriez aussi bien tout faire dans la coquille.Cette solution fonctionne sous MacOSX 10.7. Cela fonctionne à merveille.
Dans mon cas
ou
nettoyer mon bureau en permanence.
la source
sleep
commande là-bas?while [ 0 ]
est un moyen étrange d'écrire une boucle infinie; cela fonctionne car latest
commande (également connue sous le nom[
) traite une chaîne non vide comme étant vraie.while : ; do ... ; done
est plus idiomatique, ou si vous préférez, vous pouvez utiliserwhile true ; do ... ; done
.Vous pouvez source cette fonction récursive:
ou ajouter un:
et appelez le script.
la source
Pour exécuter de manière répétée une commande dans une fenêtre de console, je lance généralement quelque chose comme ceci:
while true; do (run command here); done
Cela fonctionne également pour plusieurs commandes, par exemple pour afficher une horloge continuellement mise à jour dans une fenêtre de console:
while true; do clear; date; sleep 1; done
la source
la source
Avec
zsh
et unesleep
implémentation qui accepte les arguments en virgule flottante:Ou pour
forever
:Si votre
sleep
ne supporte pas les float, vous pouvez toujours le redéfinir en tant que wrapper autourzsh
dezselect
:la source
... Je me demande combien de solutions compliquées peuvent être créées pour résoudre ce problème.
Cela peut être si facile ...
mettez-y 1 ligne suivante à la fin du fichier comme:
Si vous voulez exécuter quelque chose toutes les 1 secondes, mettez-y simplement:
et à l'intérieur de ce fichier.sh devrait être:
et c'est tout!
PRENDRE PLAISIR!
la source
travaille pour moi.
la source