Jak zatrzymać bash, gdy pętla działa w tle?

23

Zacząłem pętlę while w następujący sposób:

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

Zwróć uwagę na &.

Myślałem, że kiedy zabiję terminal, pętla while się zatrzyma. Ale wciąż idzie. Minęły godziny, odkąd zabiłem sesję terminalową.

Jak zatrzymać tę pętlę while?

Saqib Ali
źródło

Odpowiedzi:

38

ja zacząłem

while true; do yad; sleep 60; done &

i zamknąłem terminal, żeby go przetestować, teraz mam ten sam problem.

Jeśli terminal został już zamknięty, uruchomiłeś pętlę

Zobaczmy przegląd uruchomionych procesów ps fjx, ostatnie linie na moim komputerze przeczytane

 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)

Możesz zobaczyć yadjako podproces /bin/bash, jeśli yadgo zamknę , zmieni się sleep 60na wynik ps. Jeśli widok drzewa jest zbyt mylący, możesz również przeszukać dane wyjściowe w następujący sposób 1 :

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

Linie wyjściowe zaczynają się od dwóch liczb, z których pierwsza to PPID, identyfikator procesu nadrzędnego, a druga to PID, identyfikator samego procesu. To dlatego 9411pojawia się w obu wierszach tutaj:

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

To bashpodpowłoka, którą chcemy zabić i właśnie odkryliśmy jej PID, więc teraz wszystko, co pozostaje, jest proste

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

i irytująca podpowłoka zniknęła na dobre.

1 : Notacja „ grep "[y]ad"zamiast” po prostu grep yadzapobiega wyświetlaniu grepsamego procesu na liście wyników.


Jeśli terminal jest nadal otwarty

bashudostępnia zmienną $!, która „rozwija się do identyfikatora procesu zadania ostatnio umieszczonego w tle”, więc następujące zabija najnowszy proces w tle:

kill $!

Jeśli to nie ostatni proces, po prostu można uzyskać listę uruchomionych zadań przy jobspomocy wbudowanego Przykâadowa:

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

Na liście zadań znajdują się dwa zadania, aby zabić jedno z nich, można uzyskać do niego dostęp za pomocą numeru zadania lub skrótów %, %+(„bieżące zadanie”) i %-(„poprzednie zadanie”), np. Aby zabić pętlę działającą w tle mógłby zrobić

kill %1  # or
kill %-

i zabić zawieszoną sleep 10pracę:

kill %2  # or
kill %+  # or
kill %
deser
źródło
5

Muszę zauważyć, że po zamknięciu terminalu, w którym wprowadzono to polecenie, polecenie podrzędne powinno było umrzeć wraz z nim. Próba odtworzenia tego pokazała takie zachowanie.

Teraz, zakładając, że rzeczywiście znajdujesz się w sytuacji, w której tak się nie stało, jednym ze sposobów na zabicie programu, który pozostawiłeś uruchomiony w tle, który był spowodowany &na końcu polecenia, jest:

  1. Otwórz nową powłokę i uruchom, echo $$aby zanotować bieżący PID (identyfikator procesu), abyś nie zabił własnej sesji.
  2. Zidentyfikuj PID programu, który Twoim zdaniem nadal działa; możesz to zrobić za pomocą ps -ef | grep $SHELLpolecenia, aby dowiedzieć się, które programy uruchamiają powłokę.
  3. Zwróć uwagę na drugą kolumnę od lewej i zanotuj wartość liczbową, która różni się od echo $$powyższego wyniku; to jest PID, który chcesz zabić.
  4. Uruchom kill -SIGTERM <pid>polecenie, gdzie <pid>jest wartością liczbową zidentyfikowaną w kroku 3
  5. Potwierdź, że program już nie działa, powtarzając krok # 2

Możesz także ponownie uruchomić sesję lub komputer, ale powyższe pozwoli ci tego uniknąć.

kod_dredd
źródło
2
Możesz także użyć topdo zabicia procesu, naciskając k, następnie wprowadzając PID, a następnie naciskając dwukrotnie klawisz Enter.
luk3yx
-1

&Uczyni terminal utworzyć nowy proces i otrzymać kod do uruchomienia w środku. Twój kod staje się więc niezależny od procesu końcowego. Nawet jeśli zamkniesz terminal, nowy proces, w którym działa Twój kod, nie zostanie zatrzymany. Więc usuń &lub zrób ps -aux, zlokalizuj swój proces i zabij go kill (process id).

Dr4ke the b4dass
źródło
-3

Zwykle bg dla tła fg dla pierwszego planu. Jeśli użyjesz & symbol użyj fg, wyświetli się aktualnie uruchomiony program. Naciśnij Ctrl + C, aby zabić.

Ciekawy
źródło
3
Używanie bg/ fgnie będzie działać po odłączeniu terminala bash. Nie można ponownie podłączyć za pomocą, reptyrponieważ bashma procesy potomne ( sleep).
xiota,
Zamknął terminal, ponieważ zabije ten proces. Więc następnym razem użyje fg, aby zamknąć program. Proste
Ciekawe
@Curious to następnym razem. Ale OP pyta o ten czas.
RonJohn,