Jak zawiesić i przenieść proces tła na pierwszy plan


166

Mam proces pierwotnie uruchomiony na pierwszym planie. Zawiesiłem przez Ctrl+ Z, a następnie wznowiłem jego działanie w tle przez bg <jobid>.

Zastanawiam się, jak zawiesić proces działający w tle?

Jak mogę przenieść proces tła na pierwszy plan?

Edytować:

Proces wysyła dane do stderr, więc jak mam wydać polecenie, fg <jobid>gdy proces wysyła dane do terminala?


1
Nadal możesz wpisywać polecenia w terminalu, który wyrzuca błędy. Tekst wyrzucony na STDERR nie jest liczony jako wejście, tylko wysyłane klucze. Na ekranie wygląda myląco, ale działa.
Caleb

@Caleb: Nawet jeśli proces wyjdzie na standardowe wyjście, nadal mogę pisać, fg <jobid>aby zrobić to na pierwszym planie?
Tim

@Tim: Tak, możesz.
Caleb

Odpowiedzi:


214

Jak powiedział Tim, wpisz, fgaby sprowadzić ostatni proces z powrotem na pierwszy plan.

Jeśli w tle działa więcej niż jeden proces, wykonaj następujące czynności:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3aby vim 23proces ten powrócił na pierwszy plan.

Aby zawiesić proces działający w tle, użyj:

kill -STOP %job_id

Sygnał SIGSTOP zatrzymuje (zatrzymuje) proces w zasadzie w taki sam sposób, jak Ctrl+ Z.

Przykład: kill -STOP %3.

źródła: Jak wysyłać sygnały do ​​procesów w Linuksie i Uniksie oraz Jak zarządzać zadaniami w tle i na pierwszym planie .


23
sygnał 19 jest SIGCONTdla mnie; I tak używam kill -STOPi kill -CONTwolę zapamiętywać liczby, ale możesz sprawdzić, kill -laby przypomnieć sobie o wartościach liczbowych
Bezużyteczne

Proces wysyła dane do stderr, więc jak mam wydać polecenie jobi fg <jobid>kiedy proces wysyła dane do terminala?
Tim

1
@Tim Wystarczy wpisać polecenie, jak zwykle. Tak długo, jak zadanie jest w tle, nie czyta tego, co piszesz - twoja powłoka jest. To, co wpiszesz, może wyglądać na zepsute, ale powłoka dobrze to zrozumie.
AlexWebr

@AlexWebr: Dzięki, działa! (1) Czy zadanie w tle nie przyjmuje żadnych danych wejściowych i wyjściowych, w tym „Ctrl + Z” itp., Prawda? (2) Czy zadanie działające w tle może zostać bezpośrednio zawieszone? Jeśli tak to jak? Jeśli nie, czy należy go najpierw zmienić, aby działał na pierwszym planie, zanim będzie można go zawiesić?
Tim

2
Czy zadanie działające w tle może zostać zawieszone bezpośrednio tak: kill -STOP %job_idjak wyjaśniono
Bezużyteczne

31

Powinno to dotyczyć każdej powłoki z kontrolą zadań, którą (w przeważającej części) możesz brać za pewnik, chyba że masz do czynienia z naprawdę starożytną powłoką. Jest w standardzie POSIX , więc dashobsługuje nawet kontrolę zadań (uruchamiany interaktywnie lub z -m).

Interaktywny

  • Ctrl+ zzawiesi program, który jest obecnie wyświetlany
  • bgutworzy tło dla ostatnio zawieszonego programu
    (użyj bg %2z numerem zadania, który możesz sprawdzić jobs)
  • fg ujawni ostatnio zawieszony program

W zshmożesz napisać powiązanie klucza, aby niejawnie uruchamiać się fgz wiersza polecenia za pomocą innego znaku Ctrl+ z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

Prawdopodobnie istnieje również sprytny sposób, aby pośrednio uruchomić bgzawieszenie, ale wydaje się to nierozsądne; przynajmniej dla mnie większość mojego Ctrl+ zużycia wynika z tego, że Ctrl+ cnie wybucha; Chcę podążać za tym np. kill %1Zamiast bg, a na pewno nie chcę domyślnie zabijać! (Ta logika rozciąga się również na to, dlaczego nie używam już tego powiązania klawiszy: jeśli wbijam Ctrl+, zaby zatrzymać proces, ostatnią rzeczą, którą chcę, to wznowienie!)

Nieinteraktywny

Jeśli jesteś w innej instancji powłoki (lub innym użytkowniku, czasem zawierającym sudopolecenia), prawdopodobnie nie będziesz mógł używać numerów zadań.

Nadal możesz działać na innym procesie, gdy znasz jego identyfikator procesu (PID). Możesz uzyskać PID za pomocą pgrep …, lub ps aux |grep …(lub z tej samej powłoki jobs -l, lub $!), a następnie możesz uruchomić:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

Jeśli nie znasz identyfikatora procesu i nie martwisz się zawieszeniem innych instancji procesu według nazwy, możesz przekazać sygnały do ​​jednego z tych:

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

CONTSygnał do programu zatrzymana Ctrl+ z(a nie bg„d) wznowi swoje postępy (na pierwszym planie), tak samo jak gdybyś fgnim.

Odp: Błąd standardowy

Edycja tego pytania dotyczy standardowego błędu:

Proces wysyła dane do stderr, więc jak mam wydać polecenie, fg <jobid>gdy proces wysyła dane do terminala?

O ile dane zadanie nie zawiera składników, które są w tle (lub całe zadanie jest w tle, być może za pośrednictwem kill -CONT), tak naprawdę nie powinieneś widzieć wyjścia, gdy jest zawieszone.

Jeśli nadal wyprowadza dane (czy to na standardowe wyjście, czy na standardowy błąd), z pewnością spowoduje to, że twój terminal będzie zaśmiecony wizualnie, ale wszystkie te dane wyjściowe zostaną zignorowane, ponieważ nie są częścią twojego wejścia. Może to utrudnić stwierdzenie, że nie wprowadzono żadnych literówek, ale fgEnterwystarczy wpisać (na ślepo) (chyba, że ​​masz wiele zadań, a to, o którym mowa, nie jest najnowsze, w takim przypadku rzeczywiście potrzebujesz deskryptora zadania ).

Jeśli potrzebujesz znaleźć deskryptor zadania, użyj innego terminala, aby wysłać mu STOPsygnał za pomocą nieinteraktywnych metod powyżej. To powinno zwolnić twój ekran (być może uderzył Enterkilka razy lub uruchom clearlub Ctrl+ L), abyś mógł następnie uruchomić jobsznaleźć deskryptor zadania, a następnie uruchomić fg %Ntam, gdzie Njest ta liczba.


Jedynym problemem związanym z wstrzymywaniem i wznawianiem procesów jest to, że jeśli wykonałeś jakiekolwiek połączenia z innym programem (na przykład RabbitMQ), połączenie zostanie utracone po wznowieniu.
Nav

@Nav - To dlatego, że nie uruchomiłeś go bez głowy. W bash i zsh uważam, że po prostu potrzebujesz odrzucić proces działający w tle. Wolę uruchamiać takie zadania za pomocą nohup lub terminalowego multipleksera, takiego jak screen lub tmux . Nie możesz wybrać procesu nohup (tak jak nie możesz wznowić procesu w tle z oddzielnego połączenia), ale możesz połączyć się z multiplekserem.
Adam Katz

To był proces w tle. Zamknąłem terminal, a następnie zalogowałem się na serwerze z innego terminala.
Nav

Tak, nie można wznowić procesu z innej powłoki, chyba że został on uruchomiony z myślą o tym. Polecam do tego screen lub tmux.
Adam Katz

Uważam, że jeśli wyślesz CONTsygnał do procesu (zadanie / potok) zatrzymanego za pomocą Ctrl + Z, wznowi się w tle, nawet jeśli go nie zrobiłeś bg.
G-Man,

10

Wpisz, fgaby przenieść go na pierwszy plan.


Dzięki! Proces wysyła dane do stderr, więc jak mam wydać polecenie, fg <jobid>gdy proces wysyła dane do terminala?
Tim

1
  1. wyświetlać zadania za pomocą jobspolecenia
  2. Przenieś swoją docelową pracę na pierwszy plan dzięki fg; na przykład: fg %4
  3. Naciśnij, CTRL Zaby zawiesić
  4. Aby uruchomić go w tle, użyj bg; na przykład:bg %4

0

Zakończenie procesu można wykonać na kilka różnych sposobów. Często po wydaniu polecenia opartego na konsoli wysłanie Ctrlcnaciśnięcia klawisza (domyślny znak przerwania) spowoduje wyjście z polecenia. Działa to, gdy proces działa w trybie pierwszego planu.

Jeśli proces działa w tle, najpierw musisz uzyskać jego identyfikator zadania za pomocą pspolecenia, a następnie możesz użyć polecenia kill, aby zabić proces w następujący sposób:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Tutaj killpolecenie zakończy first_oneproces. Jeśli proces ignoruje zwykłe killpolecenie, możesz użyć kill -9identyfikatora procesu w następujący sposób:

$kill -9 6738
Terminated

1
Chociaż jest to prawda, nie odpowiada na pytanie ...
jasonwryan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.