Bash Loop - Як зупинити цикл, коли я натискаю Control-C всередині команди?


35

Я перекладаю кілька каталогів. У мене відкритий термінал bash і я виконую щось подібне:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

Однак якщо я хочу зупинити всі справи, натискаю Control-C. Це зупиняє rsync, але потім він продовжує переходити до наступного. У цьому випадку я усвідомлюю, що сталося, і тоді просто натискаю Control-C, як божевільний, поки все знову не вийде.

Чи є якийсь спосіб це виправити. Я хочу так, якщо у мене є такий цикл, і натисніть Control-C, щоб він повернув мене до моєї башти.


6
Відповідь Денніса є правильною, але якщо ви цього не зробили, вам не доведеться «натискати на неї, як божевільний», просто потримайте її і дозвольте клавіатурі повторити обробку :-)
Кайл Брандт,

Я завжди просто утримую Cntl-C, як правило, працює добре.
Скотт Алан Міллер

Відповіді:


33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

Це також вийде з циклу, якщо окремий запуск rsync з якоїсь причини вийде з ладу.


4
Додаткова порада: якщо ви знаходитесь у вкладеному циклі і хочете повністю припинити, скористайтеся break 2(або замініть "2" на кількість вкладених циклів, які ви хочете припинити).
Dolan Antenucci

26

Щоб розширити відповідь Денніса, ваш код може виглядати так:

trap "echo Exited!; exit;" SIGINT SIGTERM

Для робочого прикладу (який, зокрема, включає rsync), перегляньте http://gist.github.com/279849 .


Дякую, це загальне рішення, яке працювало для мене
wi1


6

Коли ви помістите рядок команд всередині дужок, рядок буде діяти як єдиний процес, і він отримає SIGINT і завершиться при натисканні Ctrl- C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

Але! У випадку rsyncкоманди вона дозволяє декілька джерел, тому код, який ви написали, було б краще записати як:

rsync -a * example.com:somewhere/

6
  1. Натисніть, Ctrl-Zщоб призупинити сценарій;
  2. kill %%

Кредити, пояснення та більше деталей у цій відповіді .


Це чудово, тому що він працює "пост-факто", коли ви хочете перервати вже запущений цикл, який ви вже почали.
Нік Маттео

0

Я схильний вводити ще одну команду у свій цикл, яку легко перервати. Для цього потрібно натиснути два ctrl-C.

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

Це не таке чудове рішення для цієї rsync, яку, напевно, хочеться швидко запустити. Але це добре працює для інших циклів, як ця:

while true ; do ping -c 10 example.com ; sleep 1 ; done

Цей цикл буде повторно шукати адресу example.com кожен раз через цикл, що корисно, якщо ви спостерігаєте за зміною DNS.

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