Come sospendere e portare in primo piano un processo in background


167

Ho un processo originariamente in esecuzione in primo piano. Ho sospeso di Ctrl+ Z, quindi ho ripreso la sua esecuzione in background da bg <jobid>.

Mi chiedo come sospendere un processo in esecuzione in background?

Come posso portare in primo piano un processo in background?

Modificare:

Il processo viene emesso su stderr, quindi come devo emettere il comando fg <jobid>mentre il processo viene inviato al terminale?


1
È ancora possibile digitare comandi in un terminale che sta emettendo errori. Il testo emesso su STDERR non conta come input, solo i tasti che invii. Sembra confuso sullo schermo ma funziona.
Caleb,

@Caleb: anche quando il processo viene emesso su stdout, posso comunque digitare fg <jobid>per renderlo in primo piano?
Tim

@ Tim: Sì, puoi.
Caleb,

Risposte:


216

Come ha detto Tim, digita fgper riportare in primo piano l'ultimo processo.

Se hai più di un processo in esecuzione in background, procedi come segue:

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

fg %3per riportare il vim 23processo in primo piano.

Per sospendere il processo in esecuzione in background, utilizzare:

kill -STOP %job_id

Il segnale SIGSTOP arresta (mette in pausa) un processo essenzialmente allo stesso modo Ctrl+ Z.

Esempio: kill -STOP %3.

fonti: come inviare segnali ai processi in Linux e Unix e come gestire i lavori in background e in primo piano .


23
il segnale 19 è SIGCONTper me; Uso kill -STOPe kill -CONTpreferisco ricordare i numeri comunque, ma puoi controllare kill -lper ricordarti dei valori numerici
Inutile

Il processo viene emesso su stderr, quindi come devo inviare il comando jobe fg <jobid>mentre il processo viene inviato al terminale?
Tim

1
@ Tim Basta digitare il comando normalmente. Finché il lavoro è in background, non sta leggendo ciò che si digita - lo è la shell. Quello che scrivi potrebbe sembrare scomposto, ma la shell lo capirà bene.
AlexWebr,

@AlexWebr: Grazie, funziona! (1) Un lavoro in background non accetta input e output tra cui "Ctrl + Z" ecc., Giusto? (2) Un lavoro in esecuzione in background può essere sospeso direttamente? Se si, come? In caso negativo, deve essere prima modificato per essere eseguito in primo piano prima di poter essere sospeso?
Tim

2
Un lavoro in esecuzione in background può essere sospeso direttamentekill -STOP %job_id
:,

31

Questo dovrebbe essere vero per qualsiasi shell con controllo del lavoro, che (per la maggior parte) si può dare per scontato a meno che non si tratti di una shell veramente antica. È nello standard POSIX , quindi dashsupporta anche il controllo dei lavori (quando eseguito in modo interattivo o con -m).

Interactive

  • Ctrl+ zsospenderà il programma attualmente in primo piano
  • bgmetterà in background il programma sospeso più recente
    (utilizzare bg %2con il numero lavoro, che è possibile verificare con jobs)
  • fg metterà in primo piano il programma sospeso più recente

In zsh, puoi scrivere un'associazione chiave per eseguire implicitamente fgdal prompt tramite un altro Ctrl+ z:

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

Probabilmente c'è anche un modo intelligente per correre implicitamente bgalla sospensione, ma sembra poco saggio; almeno per me, la maggior parte del mio Ctrl+ zutilizzo è perché Ctrl+ cnon riesce a scoppiare; Voglio seguirlo con ad es. kill %1Anziché con bg, e certamente non voglio per impostazione predefinita uccidere! (Questa logica si estende anche al motivo per cui non uso più questa associazione di tasti: se sto martellando Ctrl+ zper interrompere un processo, l'ultima cosa che voglio che faccia è riprendere!)

Non interattiva

Se ti trovi in ​​una diversa istanza della shell (o in un altro utente, a volte includendo sudocomandi), probabilmente non sarai in grado di utilizzare i numeri di lavoro.

È ancora possibile agire su un altro processo una volta che si conosce l'ID processo (PID). È possibile ottenere il PID con pgrep …, o ps aux |grep …(o dalla stessa shell jobs -l, o $!) e quindi eseguire:

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

Se non si conosce l'ID del processo e non si è preoccupati di sospendere altre istanze del processo per nome, è possibile passare segnali a uno di questi:

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

Un CONTsegnale ad un programma fermato con Ctrl+ z(e non bg'd) riprenderà il suo progresso (in primo piano), come se fossi in fgesso.

Ri: Errore standard

La modifica a questa domanda richiede un errore standard:

Il processo viene emesso su stderr, quindi come devo emettere il comando fg <jobid>mentre il processo viene inviato al terminale?

A meno che il lavoro in questione non abbia componenti in background (o l'intero lavoro sia in background, forse tramite kill -CONT), non dovresti effettivamente vedere l'output mentre è sospeso.

Se sta ancora trasmettendo dati (che si tratti dell'output standard o dell'errore standard), renderà sicuramente disordinato il terminale, ma tutto quell'output verrà ignorato poiché non fa parte dell'input. Ciò potrebbe rendere più difficile sapere che non hai inserito alcun refuso, ma la digitazione (alla cieca) fgEnterdovrebbe essere sufficiente (a meno che tu non abbia più lavori e quello in questione non è il più recente, nel qual caso avrai davvero bisogno del descrittore di lavoro ).

Se è necessario trovare il descrittore di lavoro, utilizzare un altro terminale per inviare il STOPsegnale tramite i metodi non interattivi sopra. Questo dovrebbe liberare il tuo display (forse premere Enteralcune volte o eseguire clearo Ctrl+ L) in modo da poter quindi eseguire jobsper trovare il descrittore di lavoro e quindi eseguire fg %Ndove si Ntrova quel numero.


L'unico problema con la sospensione e la ripresa dei processi è che se si effettuano connessioni ad altri programmi (come RabbitMQ per esempio), la connessione andrebbe persa quando si riprende.
Nav

@Nav - Questo perché non l'hai eseguito senza testa. In bash e zsh, credo che tu debba semplicemente rinnegare un processo in background. Preferisco eseguire tali attività con nohup o un terminale multiplexer come screen o tmux . Non è possibile avviare un processo nohup (così come non è possibile riprendere un processo in background da una connessione separata), ma è possibile connettersi a un multiplexer.
Adam Katz,

È stato un processo in background. Avevo chiuso il terminale e quindi eseguito l'accesso al server da un altro terminale.
Nav

Sì, non puoi riprendere un processo da un'altra shell a meno che non sia stato avviato con questo in mente. Raccomando schermo o tmux per quello.
Adam Katz,

Credo che se si invia un CONTsegnale a un processo (lavoro / pipeline) interrotto con Ctrl + Z, riprenderà in background, anche se non l'hai bgfatto.
G-Man,

10

Digita fgper portarlo in primo piano.


Grazie! Il processo viene emesso su stderr, quindi come devo emettere il comando fg <jobid>mentre il processo viene inviato al terminale?
Tim

1
  1. elenca i lavori con jobscomando
  2. Porta in primo piano il tuo lavoro di destinazione fg; per esempio: fg %4
  3. Hit CTRL Zper sospendere
  4. Per avviarlo in esecuzione in background, usa bg; per esempio:bg %4

0

La conclusione di un processo può essere eseguita in diversi modi. Spesso, da un comando basato su console, l'invio di una Ctrlcsequenza di tasti (il carattere di interruzione predefinito) uscirà dal comando. Funziona quando il processo è in esecuzione in modalità primo piano.

Se un processo è in esecuzione in modalità background, prima devi ottenere il suo ID lavoro usando il pscomando e dopo puoi usare il comando kill per terminare il processo come segue:

$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

Qui il killcomando terminerebbe il first_oneprocesso. Se un processo ignora un killcomando regolare , è possibile utilizzare kill -9seguito dall'ID processo come segue:

$kill -9 6738
Terminated

1
Mentre questo è vero, non sta rispondendo alla domanda ...
Jasonwryan,
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.