Processi in background senza "&"


24

Supponiamo che tu abbia avviato una nuova applicazione in Linux (come un editor di testo, ecc.), Ma hai dimenticato di usare "&". Quali comandi useresti per far funzionare quel processo in background, senza dover chiudere l'applicazione? In questo modo, è possibile avere entrambi i processi aperti e funzionanti separatamente (ad esempio, il terminale della riga di comando utilizzato per creare il processo e il processo come un editor di testo ancora in esecuzione.?


Tecnicamente no, ma forse tmuxoffre le stesse funzionalità desiderate nella tua domanda.
MK

1
Non trascurare la semplice alternativa di aprire un'altra shell quando possibile.
jpmc26,

Risposte:


43

Nella finestra del terminale in genere si digita Control+ Zper "sospendere" il processo e quindi utilizzare il bgcomando per "sfondo".

ad es. con un comando sleep

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

Possiamo vedere che il processo è in esecuzione e ho ancora la mia riga di comando.


5
Potrebbe essere interessante aggiungere che il processo può essere riportato in primo piano con il fgcomando, che accetta l'id del lavoro (specificato tra parentesi, 1in questo caso) come parametro. Non è specifico per l'uso di bge può essere fatto su processi avviati con &.
Aaron,

14

Ctrl+ Zè il modo di farlo, ma solo per completezza: la domanda chiede "comando", e sarebbe (da un altro terminale):

kill -STOP pid_of_the_running_applications

e poi ovviamente

bg

dal terminale dell'applicazione.


6
uccidi -STOP e poi uccidi -CONT
Michel Billaud il

10

In Bash:

Ctrl+ Ze poi bg.

Ora corri jobse guarda il risultato.


2
@grooveplex Tomas ha risposto per primo, quindi sarebbe più appropriato commentare sotto la risposta di Stephen, che la sua è sostanzialmente la risposta di Tomas con qualche dettaglio in più.
Anthon,

2
In realtà abbiamo risposto contemporaneamente. Non sorprende che entrambi abbiamo detto la stessa cosa poiché è la risposta ovvia :-) Nessuno dei due ha copiato l'altro. La mia risposta è arrivata poco dopo quella di Thomas perché avevo speso del tempo in più per creare e formattare l'esempio.
Stephen Harris,

1
E il mio dice che è in Bash, quindi non sono gli stessi.
Tomasz,

1
Heh, c'è un punto potenziale lì. Richiede che la shell abbia il controllo del lavoro. Alcune delle prime macchine su cui ho lavorato (basato su SVr2) non avevano questo /bin/she quindi questo non avrebbe funzionato :-)
Stephen Harris

1

Come misura preventiva per l'inconveniente di dover premere CTRL- z, potresti creare uno script wrapper per il tuo editor sul quale eseguire il tuo editor in background. In questo modo non avresti bisogno di occuparti di ricordare di avviarlo in background esplicitamente:

    #!/bin/sh

    EDITOR="emacs" # or whatever

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

Sopra proviamo prima a determinare se hai X server disponibile e solo allora esegui l'editor in background (in caso contrario, molti editor Unix useranno invece il tuo terminale e in questo caso non vuoi eseguire l'editor come processo in background) . Passerà tutti gli argomenti al tuo editor di scelta verbatim ( "$@") proprio come hai fornito per lo script wrapper.

Per quanto riguarda il comando che ti manca ... Secondo la mia sperimentazione di base, per i programmi della GUI che non coinvolgono il terminale, potrebbe essere semplice come prima l'invio SIGSTOPe poi SIGCONTal processo in primo piano (usando il killcomando se usi lo script della shell per implementarlo) . Ovviamente dovresti eseguirlo in un'altra finestra / scheda del terminale e la difficoltà sarebbe quella di trovare in modo generico e generico il PID a cui desideri inviare il segnale. Per impostazione predefinita, è possibile inviare i due segnali a tutti i processi del nome specificato (impostazione predefinita per l'editor preferito e consentire l'utilizzo di PID anche come argomenti):

    #!/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

Questo metodo mi ha dato correttamente le mie schede dei terminali dopo aver eseguito (diversi) emacscomandi in background. Ma il processo emacs in esecuzione nel terminale non è stato ripristinato correttamente a causa del controllo del lavoro della shell o della confusione delle impostazioni del terminale. Quindi questo metodo trarrebbe beneficio da alcune sofistificazioni.

Il SIGSTOPè esattamente ciò che è inviare al processo in primo piano quando si preme (per default comuni) CTRL- z. Fare riferimento stty -aall'output

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

(uscita abbreviata) e sttypagina del manuale:

   susp CHAR
          CHAR will send a terminal stop signal

I processi arrestati utilizzando il SIGSTOPsegnale possono essere riavviati inviando SIGCONT. Normalmente è la logica di controllo del lavoro della shell che invierà SIGCONTe prenderà cura di altre manipolazioni necessarie coinvolte fge bgcomandi che ignoriamo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.