Постійно повторно виконайте команду, коли вона закінчиться в Bash


62

Я намагаюся знайти простий спосіб тримати повторне виконання команди з будь-якої причини (помилка чи інше).

Який найкращий спосіб підійти до цього?

EDIT: Раніше я був недостатньо зрозумілий. Наступне виконання мені потрібно чекати, поки завершиться попереднє.

EDIT 2: Майже всі відповіді чудово працюють. Я помилково подумав, що більшість відповідей буде або роздрібнити процес, або повторно виконати його лише один раз, жоден з яких не потрібен.

linux  bash 

1
Ви все ще не зрозуміли. Це допоможе, якщо ви згадали, яку програму виконуєте.
Даніель Бек

1
-1 Це питання не показує жодних зусиль для дослідження, оскільки користувач прокоментував, що відповіді не спрацювали, а не намагалися робити те, що пропонують.
Даніель Бек

Відповіді:


39

Це створює нескінченний цикл, виконуючи commandзнову і знову.

while :
    do
        command
done

Будь ласка, дивіться редагування оригінального запитання. Мені потрібно постійно повторювати його не раз, а лише один раз.

8
@calcifer Ця відповідь працює досить добре. У вашій програмі є щось незвичне, про що ніхто з чотирьох відповідей, що відповіли, поки що не очікував, і ви не змогли це згадати.
Даніель Бек

@calcifer це нескінченна петля. це повторюється до кінця часу (ну, поки сценарій все одно не буде припинено)
Нейт Коппенгавер

1
Моє погано, я думав, що це (і всі інші відповіді) буде або роздрібнити процес, або повторно виконати його лише один раз, жоден з яких не потрібен. Так, так, ця відповідь працює. Дякую.

1
версія для одного рядка: while true; do echo 'Hit CTRL+C'; sleep 1; doneзавдяки cyberciti.biz/faq/bash-infinite-loop
jk2K

107

watchКоманда повторить команду назавжди з інтервалом , зазначеним:

watch -n0 <command>

Якщо встановити -nнуль, ефективність просто не ставить нічого (я думаю, що це дійсно .1 секунда).

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

Довідка: сторінка чоловіка годинника :

watch виконує команду неодноразово, показуючи її вихід (перший скріншот). Це дозволяє спостерігати за зміною вихідних програм у часі. За замовчуванням програма запускається кожні 2 секунди; використовуйте -n або --interval, щоб вказати інший інтервал.

годинник буде працювати, поки не перерветься.


Будь ласка, дивіться редагування оригінального запитання.

6
Усі відповіді на даний момент роблять це, включаючи цю. Linux не розщедриться, якщо ви спеціально не попросите цього.
Павло

Я не знав цього про виделку, дякую.

Я не бачу жодного виводу за допомогою цього методу.
Раффі Хатчадуріан

@RaffiKhatchadourian Ви говорите, якщо ви робите watch lsв каталозі, який містить файли, ви нічого не отримуєте?
Поль

17

Простим рішенням буде:

yourcommand; !#

;відокремлює команди, допускаючи кілька команд в одному рядку ( Bash: Списки )

!#каже Башу "повторити все, що я написав до цього часу в цьому рядку" ( Bash: Події-дизайнери )


1
Вибачте, я був недостатньо зрозумілий. Мені потрібно постійно повторювати його не раз, а лише один раз.

Дякую за це, я шукав це, тим більше, yourcommand; !!що насправді не працює з командами в одному рядку, однак, !#схоже, це і робиться. Ура!
sdaau

; !#не працював на ZSH, він просто розширює заяву, по суті клонуючи її, не запускає
revelt

7

Ви можете планувати заздалегідь під час виконання команди (за умови, що це не інтерактивна робота) та вводити, !!яка виконає попередню команду знову. Це працює, наприклад, під час ping -c 5.


Ви також можете визначити функцію в bash:

function repeat { "$@"; "$@"; }

Щоб зберегти його, зберігайте його ~/.bashrc.

Потім ви можете запустити свою команду так:

repeat ping -c5 heise.de

Якщо це певна команда, яку ви хочете неодноразово виконувати (а не, наприклад, будь-яка команда), ви можете замінити "$@"в цьому фрагменті фактичну команду та repeat_pingзамість неї назвати функцію, наприклад .


Щоб зробити це нескінченним циклом, ви можете зробити те, що пропонує @Dennis. Рекомендую вам додати період очікування, якщо ви збираєтесь використовувати це в інтерактивній оболонці, наприклад:

function repeat { while 1 ; do "$@" ; sleep 1 ; done; }

Інакше скасувати цю нескінченну петлю досить незручно Ctrl-Z.


Будь ласка, дивіться редагування оригінального запитання.

6
@calcifer Ці виконання чекають, поки повернеться програмний виклик. Чи відключається ваша програма від оболонки та повертається до завершення роботи?
Даніель Бек

Моє погано, я думав, що це (і всі інші відповіді) буде або роздрібнити процес, або повторно виконати його лише один раз, жоден з яких не потрібен. Так, так, ця відповідь працює. Дякую.

4

Надайте whileциклу булеві умови, такі як:

#!/bin/bash

while true; do

    do_something && wait

done

Це буде виконуватися знову і знову, поки bash не отримає сигнал про припинення процесу. Зазвичай у формі ctrl+c.

Ви також можете скористатися watchкомандою для повторного запуску сценарію. Наприклад, простий годинник у вашому терміналі bash watchможе виглядати так:

$ watch -t -n1 date +%T

-tОпція вказує , watchщоб не відображати назву процесу він працює. Це дає чіткий вихід лише тієї команди, яка повторюється. -n1Опція каже дивитися повторювати кожні nсекунди. У цьому випадку -n1будуть проміжки 1секунди. Потім date +%Tкоманда показує час на момент виконання команди. Виконання цієї команди дасть вам активний годинник у вашому терміналі.

І тоді ще одним методом, якого немає в жодній з інших відповідей, буде нескінченний виклик функції.

do_something() { do_something }; do_something && wait

Це по суті те саме, що булевий whileцикл лише за допомогою рекурсивних викликів функцій.

(редагувати) Для того, щоб пам’ятати про ресурси вашої машини, я додав && waitтак, що кожного разу, коли процес запускається, петлі будуть «чекати», поки цей процес закінчиться статусом виходу 0 до наступної ітерації. Це корисно в інтерактивному сценарії оболонки.


1
Існує whileприклад циклу , але він не використовує логічний trueсинтаксис. Є watchприклад, але він не дає багато корисного синтаксису. Я викладаю це щодо того, для кого це може допомогти. Я хотів надати їм практичну корисність. whileЛогічний цикл також може бути falseі не виконувати , поки НЕ відповідає дійсності умова не буде виконана. Це досить зручно.

1
@ Spittin'IT Додано метод, який не використовується в інших відповідях для вашої зручності.

Досить справедливо, і я розумію ... Я просто коментував, як я пішов через модуль огляду, але приємно редагувати та слідкувати !!
Pimp Juice IT

Як ifтримати повторне виконання?
Каміль Маціоровський

Гарна точка Каміля. Забув зробити це рекурсивно lol. Виправлено в редагуванні за допомогою функції, яка викликає себе в ifоператорі.

0

Це ще один метод, який я використовую для повторення команди в bash. Для деяких це може здатися дурним, оскільки це не передбачає написання сценарію і може бути відомим багатьом. Але я вважаю, що це варто згадати, оскільки це швидко і зручно для початківців, в тому сенсі, що синтаксису запам'ятовувати не так вже й багато. Я протестував це лише в gnome-терміналі Ubuntu, а інші термінали можуть не підтримувати це.

  1. Введіть команду в термінал один раз.
  2. Виберіть команду, що включає символ нового рядка за допомогою миші.
  3. Скопіюйте виділення за допомогою Ctrl-Insert або за допомогою контекстного меню (зазвичай доступ до нього клацніть правою кнопкою миші).
  4. Використовуйте Shift-Insert, щоб вставити стільки разів, скільки ви хочете виконати команду.

Вам не доведеться чекати, коли вставити кожну команду. Вставлені команди потрапляють у чергу і виконують одну за одною.


0

Я сьогодні відчуваю пильність.

Прочитайте з одного з нескінченних потоків і передайте його xargs

cat /dev/zero | xargs --null echo hello there

Якщо вам потрібно зробити трохи перерви там, швидше за все, вам доведеться виконати sh

cat /dev/zero | xargs --null sh -c "echo hello there && sleep 3"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.