Як зупинити баш, коли цикл працює на задньому плані?


23

Я почав цикл, а потім:

while true; do {command}; sleep 180; done &

Зауважте &.

Я думав, що коли я вбив термінал, ця петля зупиниться. Але це все одно йде. Минуло години, як я вбив термінальну сесію.

Як зупинити це під час циклу?

Відповіді:


38

я розпочав

while true; do yad; sleep 60; done &

і закрив термінал, щоб перевірити його, тепер у мене така ж проблема.

Якщо ви вже закрили термінал, ви запустили цикл

Давайте оглянемо запущені процеси ps fjx, прочитані останні рядки на моїй машині

 2226 11606 11606 19337 ?           -1 S     1000   0:00  \_ /bin/bash
11606 22485 11606 19337 ?           -1 S     1000   0:00  |   \_ sleep 10
 2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
 9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad
    1  2215  2215  2215 ?           -1 Ss    1000   0:00 /lib/systemd/systemd --user
 2215  2216  2215  2215 ?           -1 S     1000   0:00  \_ (sd-pam)

Ви можете бачити yadяк підпроцес /bin/bash, якщо я закрию yadйого зміни на sleep 60виході ps. Якщо вигляд дерева занадто заплутаний, ви також можете шукати вихід таким чином 1 :

ps fjx | grep "[y]ad"  # or respectively
ps fjx | grep "[s]leep 60"

Вихідні рядки починаються з двох чисел, перший - PPID, ідентифікатор процесу батьківського процесу, а другий - PID, ідентифікатор самого процесу. Це тому, що 9411відображається в обох рядках тут:

2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad

Це bashнижня оболонка, яку ми хочемо вбити, і ми щойно з’ясували її PID, тому тепер все, що залишається, - це просто

kill 9411  # replace 9411 with the PID you found out!

і дратівливий підрозділ пішов назавжди.

1 : Позначення grep "[y]ad"замість того, щоб просто grep yadперешкоджати появі самого grepпроцесу у списку результатів.


Якщо термінал все ще відкритий

bashнадає змінну $!, яка "розширюється на ідентифікатор процесу, який останнім часом розміщується на задньому плані", тому наступне просто вбиває останній процес у фоновому режимі:

kill $!

Якщо це не останній процес, просто ви можете отримати список запущених завдань із jobsвбудованим, наприклад, вихід:

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

Є два робочих місця в списку завдань, щоб убити одного з них ви можете отримати доступ до кількості робочих місць або ярликів %, %+( «поточної роботи») і %-( «попередня робота»), наприклад , щоб вбити цикл працює у фоновому режимі ви міг зробити

kill %1  # or
kill %-

і вбити припинену sleep 10роботу:

kill %2  # or
kill %+  # or
kill %

5

Мені потрібно зауважити, що коли ви закриваєте термінал, куди ви ввели цю команду, під команда повинна була загинути разом із нею. Спроба відтворити це показала таку поведінку.

Тепер, якщо припустити, що ви справді перебуваєте в ситуації, коли цього не сталося, один із способів вбити програму, яку ви залишили запускати у фоновому режимі, що було викликано &в кінці команди, полягає в наступному:

  1. Відкрийте нову оболонку і запустіть, echo $$щоб помітити ваш поточний PID (ідентифікатор процесу), щоб ви не вбили власний сеанс.
  2. Визначте PID програми, на вашу думку, все ще працює; це можна зробити за допомогою ps -ef | grep $SHELLкоманди, щоб знайти, які програми мають оболонку.
  3. Відмітьте другий стовпчик зліва та відзначте числове значення, яке відрізняється від echo $$результату вище; це PID, який ви хочете вбити.
  4. Виконайте kill -SIGTERM <pid>команду, де <pid>є числове значення, яке ви визначили на кроці №3
  5. Переконайтесь, що програма більше не працює, повторивши крок №2

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


2
Ви також topможете вбити процес, натиснувши k, потім ввівши PID, потім натисніть клавішу Enter двічі.
luk3yx

-1

&Змусить термінал створити новий процес і отримати код для запуску всередині нього. Таким чином ваш код стає незалежним від термінального процесу. Навіть якщо ви закриєте термінал, нещодавно процес, в якому працює ваш код, не зупиниться. Тож видаліть &або зробіть ps -aux, знайдіть процес і вбийте його kill (process id).


-3

Зазвичай bg для фонового fg для переднього плану. Якщо ви використовуєте & symbol use fg, він відображатиме поточну запущену програму. Натисніть Ctrl + C, щоб вбити.


3
Використання bg/ fgне працюватиме після від'єднання терміналу bash. Не вдасться повторно встановити додаток, reptyrоскільки bashє дочірні процеси ( sleep).
xiota

Він закрив термінал, тому що вб'є цей процес. Тож наступного разу він використовуватиме fg для закриття програми. Просто
цікаво

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