Procesy w tle bez „&”


24

Załóżmy, że uruchomiłeś nową aplikację w Linuksie (np. Edytor tekstu itp.), Ale zapomniałeś użyć „&”. Jakich poleceń użyłbyś, aby ten proces działał w tle, a jednocześnie NIE musiał zamykać tej aplikacji? W ten sposób możesz mieć otwarte i oddzielnie działające procesy (np. Terminal wiersza poleceń użyty do utworzenia procesu, a proces taki jak edytor tekstu nadal działa.


Technicznie nie, ale może tmuxzapewnia taką samą funkcjonalność, jak pożądana w pytaniu.
mkc

1
Nie zapomnij o prostej alternatywie otwierania kolejnej powłoki, jeśli to możliwe.
jpmc26,

Odpowiedzi:


43

W oknie terminala zwykle należy wpisać Control+, Zaby „zawiesić” proces, a następnie użyć bgpolecenia, aby „w tle” go.

np. z poleceniem uśpienia

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

Widzimy, że proces jest uruchomiony i nadal mam swoją linię poleceń.


5
Interesujące może być dodanie, że proces można przywrócić na pierwszy plan za pomocą fgpolecenia, które przyjmuje 1jako parametr identyfikator zadania ( w tym przypadku podany w nawiasach kwadratowych ). Nie jest on specyficzny dla użycia bgi można to zrobić w procesach uruchomionych za pomocą &.
Aaron,

14

Ctrl+ Zjest sposobem, aby to zrobić, ale tylko dla kompletności: pytanie wymaga „polecenia”, a byłoby to (z innego terminala):

kill -STOP pid_of_the_running_applications

a potem oczywiście

bg

z terminala aplikacji.


6
kil -STOP, a następnie zabij -CONT
Michel Billaud

10

W Bash:

Ctrl+ Za następnie bg.

Teraz uruchom jobsi zobacz wynik.


2
@grooveplex Tomas odpowiedział jako pierwszy, więc właściwsze byłoby skomentowanie poniżej odpowiedzi Stephena, że ​​jest to w zasadzie odpowiedź Tomasza z bardziej szczegółowymi szczegółami.
Anthon

2
Właściwie odpowiedzieliśmy jednocześnie. Nic dziwnego, że oboje powiedzieliśmy to samo, ponieważ jest to oczywista odpowiedź :-) Żadne z nas nie skopiowało drugiej. Moja odpowiedź dotarła wkrótce po Thomasie, ponieważ spędziłem dodatkowy czas na tworzeniu i formatowaniu przykładu.
Stephen Harris,

1
A moje mówi, że jest w Bash, więc nie są takie same.
Tomasz

1
Heh, jest tam potencjalny punkt. Wymaga od powłoki kontroli zadań. Niektóre z pierwszych maszyn, na których pracowałem (oparte na SVr2) nie miały tego, /bin/shwięc to by nie działało :-)
Stephen Harris

1

Jako środek zapobiegawczy związany z niedogodnością związaną z koniecznością naciskania CTRL- zmożesz utworzyć skrypt opakowujący dla swojego edytora, który uruchamiałby twój edytor w tle. W ten sposób nie będziesz musiał pamiętać o uruchomieniu go w tle:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Powyżej próbujemy najpierw ustalić, czy masz dostępny serwer X, a dopiero potem uruchomić edytor w tle (jeśli nie, wielu edytorów uniksowych zamiast tego użyje twojego terminala i w tym przypadku nie chcesz uruchamiać edytora jako procesu w tle) . Prześle wszystkie argumenty do edytora wyboru verbatim ( "$@"), tak jak podałeś dla skryptu opakowania.

Jeśli chodzi o polecenie, którego brakuje ... Na podstawie mojego podstawowego eksperymentu, dla programów GUI, które nie wymagają terminala, może to być tak proste, jak najpierw wysłanie, SIGSTOPa następnie SIGCONTprzejście do pierwszego planu (użycie killpolecenia, jeśli używasz skryptu powłoki, aby to zaimplementować) . Oczywiście musiałbyś uruchomić go w innym oknie / zakładce terminala, a trudność polegałaby na wygodnym i ogólnym znalezieniu PID, do którego chcesz wysłać swój sygnał. Możesz domyślnie wysłać dwa sygnały do ​​wszystkich procesów o podanej nazwie (domyślnie do twojego ulubionego edytora i pozwalając również używać PID jako argumentów):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

Ta metoda poprawnie dała mi karty terminalu po uruchomieniu (kilku) emacspoleceń w tle. Ale proces emacs działający w terminalu nie został poprawnie przywrócony z powodu kontroli zadań powłoki lub pomyłki w ustawieniach terminala. Ta metoda skorzystałaby z pewnego wyrafinowania.

To SIGSTOPjest dokładnie to, co jest wysyłane do procesu pierwszego planu po naciśnięciu (według typowych ustawień domyślnych) CTRL- z. Sprawdź stty -adane wyjściowe

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(wyjście skrócone) i sttystrona podręcznika:

   susp CHAR
          CHAR will send a terminal stop signal

Procesy zatrzymane za pomocą SIGSTOPsygnału można ponownie uruchomić, wysyłając SIGCONT. Zwykle jest to logika kontroli zadania powłoki, która wyśle SIGCONTi zajmie się innymi niezbędnymi manipulacjami fgi bgpoleceniami, które ignorujemy.

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.