Синтаксис для однорядного Bash нескінченного циклу


633

У мене виникають проблеми з правильним поєднанням крапки з комою та / або дужками. Я хотів би це зробити, але як однолінійний з командного рядка:

while [ 1 ]
do
    foo
    sleep 2
done

4
замініть нові рядки крапками з комою. Те саме працює для петель.
Том

23
@Tom: це не завжди працює. Після цього у вас повинна бути перша команда, а не крапка з комою
Стефано Борині

Відповіді:


1230
while true; do foo; sleep 2; done

До речі, якщо ви введете його як багаторядковий (як ви показуєте) у командному рядку, а потім зателефонуйте історію стрілкою вгору, ви отримаєте її в одному рядку, правильно розділеному знаком.

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

2
"якщо ви введете його як багаторядковий (як ви показуєте) у командному рядку, а потім викликаєте історію стрілкою вгору, ви отримаєте її в одному рядку, правильно розділеному пунктом." не було правдою для мене.
Вінсент Шейб

@VincentScheib, позначте cmdhistопцію, якщо ви використовуєте bash?
Алок Сінгал

Відмінно! Відмінно працює на Mavericks (Mac OS-X 10.9) і дозволяє мені тримати vpn. Openconnect від’єднується через кілька годин із помилкою помилки файлів cookie. Тому я помістив команду openconnect в сценарій оболонки, sudo su, щоб стати root, і використовую цей cmd рядок: while true; do sh /Users/myuser/bin/vpn ; done
Blisterpeanuts

170

Також можна використовувати команду сну в режимі, поки він знаходиться. Зробіть однолінійний вигляд більш чистим.

while sleep 2; do echo thinking; done

16
Ну, це більше, ніж просто зміна синтаксису - він виконує команду після сну. У попередній відповіді команда виконується відразу. Просто щось зауважити.
DanGordon

@DanGordon while echo thinking ; do sleep 2 ; done Звичайно, якщо команда [while] не вдасться, цикл завершується, тож вам доведеться це зробити, while echo thinking || true ; do sleep 2 ; doneале тоді ви повернетесь доwhile true ; ...
Брайан Карчіч

69

Колона завжди "справжня":

while :; do foo; sleep 2; done

15
чому товста кишка завжди правдива?
Юрген Пол

8
@ Ананас під морем: зі сторінки bash man: (у розділі SHELL BUILTIN COMMANDS) : [arguments] Без ефекту; команда не робить нічого, крім розширення аргументів та виконання будь-яких заданих перенаправлень. Повертається нульовий код виходу.
Адріан Ш

2
цей синтаксис рекомендується як: є частиною самої оболонки, тобто: є командою, побудованою оболонкою.
avner

@analytik, ти кажеш, це плюс чи мінус? ;-)
Брайан Карчіч

33

Ви можете використовувати крапки з комою для розділення виписок:

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

3
Мені подобається ця відповідь, тому що вона пояснює, коли і чому; (крапка з комою).
Містер АндреасГео

29

Ви також можете скористатися untilкомандою:

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

Зауважте, що на відміну від while, untilвиконував би команди всередині циклу до тих пір, поки умова тесту має статус виходу, який не дорівнює нулю.


Використання whileциклу:

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

Використання forциклу:

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

Інший спосіб використання until:

until [ ]; do foo; sleep 2; done

until ((0)); do foo; sleep 2; doneЧи не схоже на роботу. Це безперервне нескінченне.
030

11

Дуже проста нескінченна петля .. :)

while true ; do continue ; done

З вашого питання це було б:

while true; do foo ; sleep 2 ; done

8

Мені подобається використовувати крапки з комою лише для оператора WHILE, а оператор && змушує цикл робити більше, ніж одне.

Тому я завжди роблю це так

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
Ну, використання &&циклу таке саме, як і будь-який інший час насправді не так. Чи потрібно, щоб друге, що трапилося, тільки якщо відбудеться перше, тоді використовувати &&інше ;достатньо. Дійсно, ви хочете, щоб вміст цього циклу був коротким та простим, в ідеалі - лише однією командою, тобто функцією чи сценарієм.
thecoshman


6

Використання while:

while true; do echo 'while'; sleep 2s; done

Використання forциклу:

for ((;;)); do echo 'forloop'; sleep 2; done

Використання Recursion, (трохи інше, ніж вище, перерва на клавіатурі не зупинить це)

list(){ echo 'recursion'; sleep 2; list; } && list;

5

Якщо ви хочете, щоб цикл while зупинився після деякої умови, і ваша fooкоманда повертає ненульовий показник, коли ця умова виконана, ви можете отримати цикл, щоб розірватися так:

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

Наприклад, якщо fooкоманда видаляє речі партіями, і вона повертає 1, коли не залишається нічого для видалення.

Це добре працює, якщо у вас є власний скрипт, якому потрібно виконувати команду багато разів, до певної умови. Ви пишете сценарій для виходу з, 1коли умова виконана, і вихід з, 0коли її слід запустити знову.

Наприклад, скажімо, що у вас є сценарій python, batch_update.pyякий оновлює 100 рядків у базі даних та повертає, 0якщо є більше для оновлення та 1якщо їх більше немає. Наступна команда дозволить вам оновлювати рядки 100 одночасно із сплячим режимом протягом 5 секунд між оновленнями:

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

і як би ви вийшли?
AK_

Ви робите fooкоманду вихід з кодом, 1коли ви хочете, щоб цикл while перервався. Я оновив свою відповідь прикладом.
Yep_It's_Me

2

Якщо я можу навести два практичні приклади (з трохи "емоції").

Це записує ім'я всіх файлів, які закінчилися ".jpg" у папку "img":

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

Це видаляє їх:

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

Просто намагаюся зробити свій внесок.


1
@JKnight - для цих прикладів, що ви не просто робити ls -1 *.jpgіrm *.jpg
Кевін Fegan

2
Обидва не є нескінченними петлями і не є петлями.
Мар’ян

2

Ви також можете спробувати це ПОПЕРЕДЖЕННЯ: цього робити не слід, але оскільки питання вимагає нескінченного циклу без кінця ... ось так ви могли це зробити.

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

Навіщо ти це навіть робив?
gniourf_gniourf

2
тому що Брайан Дикон, який розмістив це запитання, хотів, як нескінченний цикл. Це більше ніж один спосіб
зібрати
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.