2009-08-17 12 views
449

Je n'arrive pas à trouver la bonne combinaison de points-virgules et/ou d'accolades. Je voudrais le faire, mais comme une seule ligne de la ligne de commande:Syntaxe d'une boucle infinie Bash à ligne unique

while [ 1 ] 
do 
    foo 
    sleep 2 
done 
+4

remplacez les nouvelles lignes par des points-virgules. La même chose fonctionne pour les boucles for. – Tom

+19

@Tom: ça ne marche pas toujours. après le faire, vous devez avoir la première commande, pas un point-virgule –

Répondre

835
while true; do foo; sleep 2; done 

Soit dit en passant, si vous tapez comme une multiligne (comme vous démontrez) à l'invite de commande puis appelez l'historique avec la flèche vers le haut, vous l'obtiendrez sur une seule ligne, correctement ponctuée.

$ while true 
> do 
> echo "hello" 
> sleep 2 
> done 
hello 
hello 
hello 
^C 
$ <arrow up> while true; do echo "hello"; sleep 2; done 
+230

+1 pour le mètre et la rime. C'est un bon moyen mnémotechnique: "while * true * do * foo * sleep * aussi * la di da": D – Shabbyrobe

+1

"si vous le tapez en multiligne (comme vous le montrez) à l'invite de commande, puis appelez l'historique avec la flèche en haut, vous l'obtiendrez sur une seule ligne, correctement ponctuée. " n'était pas vrai pour moi. –

+0

@VincentScheib, vérifiez l'option 'cmdhist' si vous utilisez bash? –

23

Vous pouvez utiliser des points-virgules pour séparer les instructions:

$ while [ 1 ]; do foo; sleep 2; done 
+0

J'aime cette réponse parce qu'elle explique quand et pourquoi; (point-virgule) est requis. –

6

J'aime utiliser les points-virgules seulement pour l'instruction while, et l'opérateur & & pour faire la boucle faire plus d'une chose. ..

donc je fais toujours comme ça

while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done 
+1

Eh bien, l'utilisation de '&&' dans la boucle est la même que toute autre fois n'est vraiment pas elle. Avez-vous besoin que la deuxième chose arrive seulement si le premier arrive, alors utilisez '&&' else ';' suffit. Vraiment, vous voulez garder le contenu de cette boucle court et simple, idéalement juste une commande, donc une fonction ou un script. – thecoshman

1

Si je peux donner deux exemples pratiques (avec un peu d '"émotion").

Ce écrit le nom de tous les fichiers est terminée par ".jpg" dans le dossier "img":

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done 

Cela les supprime:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done 

Juste essayer de contribuer.

+3

Il est plus facile de dire: '' 'for f in * .jpg; fais écho $ f; done''' – JKnight

+1

@JKnight - pour ces exemples, ne feriez-vous pas juste ** 'ls -1 * .jpg' ** et **' rm * .jpg' ** –

+2

Les deux ne sont pas des boucles infinies et pas tout boucles. – Marian

126

Il est également possible d'utiliser la commande sleep dans l'état de l'appareil. Rendre un liner plus propre imho.

while sleep 2; do echo thinking; done 
+1

bon à savoir !! –

+5

Eh bien cela fait plus que juste changer la syntaxe - il va exécuter la commande * après * le sommeil. Dans la réponse précédente, la commande est exécutée immédiatement.Juste quelque chose à noter. – DanGordon

55

Colon est toujours "true":

while :; do foo; sleep 2; done 
+11

Pourquoi le côlon est-il toujours vrai? – Michelle

+5

@Pineapple Under the Sea: A partir de la page de manuel bash: (dans la section SHELL BUILTIN COMMANDS) ': [arguments]' Aucun effet; la commande ne fait rien d'autre que d'étendre les arguments et d'effectuer des redirections spécifiées. Un code de sortie zéro est renvoyé. –

+2

Cette syntaxe est recommandée en tant que: fait partie du shell lui-même, c'est-à-dire: est une commande shell intégrée. – avner

18

Vous pouvez également utiliser la commande until:

until ((0)); do foo; sleep 2; done 

Notez que contrairement à while, until serait exécuter les commandes à l'intérieur la boucle tant que la condition de test a un statut de sortie différent de zéro.


En utilisant une boucle while:

while read i; do foo; sleep 2; done < /dev/urandom 

En utilisant une boucle for:

for ((;;)); do foo; sleep 2; done 

Une autre façon en utilisant until:

until [ ]; do foo; sleep 2; done 
+4

+1 pour une solution alternative. – glen3b

5

Une boucle infinie très simple ..:)

while true ; do continue ; done 

Fr votre question, il serait:

while true; do foo ; sleep 2 ; done 
2

Pour processus simple en regardant l'utilisation watch à la place

0

Vous pouvez essayer cela aussi AVERTISSEMENT: ce vous ne devriez pas faire, mais depuis la question demande une boucle infinie sans fin ... c'est comme ça que vous pourriez le faire.

while [[ 0 -ne 1 ]]; do echo "it's looping"; sleep 2; done 
+0

Pourquoi le feriez-vous même? –

+1

parce que Brian Deacon qui a posté la question voulait comme une boucle infinie. C'est plus d'une façon de peler un chat qui est tout –

1

Si vous voulez la boucle while pour arrêter après un certain état, et votre foo commande renvoie une valeur non nulle lorsque cette condition est remplie, vous pouvez obtenir la boucle pour briser comme ceci:

while foo; do echo 'sleeping...'; sleep 5; done; 

Par exemple, si la commande foo supprime des éléments par lots, elle renvoie 1 lorsqu'il n'y a plus rien à supprimer.

Cela fonctionne bien si vous avez un script personnalisé qui doit exécuter une commande plusieurs fois jusqu'à certaines conditions. Vous écrivez le script pour quitter avec 1 lorsque la condition est remplie et quittez avec 0 lorsqu'il doit être réexécuté. Par exemple, supposons que vous ayez un script python batch_update.py qui met à jour 100 lignes dans une base de données et renvoie 0 s'il y en a plus à mettre à jour et 1 s'il n'y en a plus. La commande suivante vous permettra de mettre à jour les lignes 100 à la fois en dormant pendant 5 secondes entre les mises à jour:

while batch_update.py; do echo 'sleeping...'; sleep 5; done; 
+0

et comment voulez-vous sortir? –

+0

Vous faites sortir la commande 'foo' avec le code' 1' quand vous voulez que la boucle while se casse. J'ai mis à jour ma réponse avec un exemple. –

Questions connexes