Come posso fare Ctrl-Z e bg in un tasto per far continuare il processo in background?


25

Seguo questo schema di sospensione dell'attività e quindi di lasciarla continuare troppo spesso con la Ctrl-Z bgsequenza.

Mi chiedevo c'è un modo per comprimerlo in un singolo tasto?

La mia shell è zsh


Voglio dire che è probabilmente un codice difficile. Ma io non sono al 100%
Chad Harrison il

Certo che lo è, ma ho trovato la soluzione elegante, grazie superuser.com/a/161922/35223
Evgeniy Dolzhenko

Risposte:


24

La sequenza Ctrl+ Zè gestita dal terminale, non dalla shell. (Background utile: qual è la differenza esatta tra un 'terminale', una 'shell', una 'tty' e una 'console'? )

Solo un piccolo set di funzioni non estendibile può essere associato a una chiave in un terminale . È possibile personalizzare i tasti associati a queste funzioni ma non aggiungere un'altra funzione. Queste funzioni rientrano in tre categorie:

  • Edizione da riga di comando in programmi che non forniscono il proprio (modalità canonica, chiamata anche modalità di cottura (in opposizione con la modalità raw), che userai raramente in pratica): end of file ( eof, Ctrl+ D), end of line ( eol, Ctrl+ M), cancella il carattere a sinistra ( erase, Ctrl+ H), cancella la parola a sinistra ( werase, Ctrl+ W), cancella la linea ( kill, Ctrl+ U).
  • Controllo manuale del flusso: stop( Ctrl+ S), start( Ctrl+ Q). Utile solo sui vecchi terminali seriali che lasciavano cadere i caratteri quando il terminale non riusciva a tenere il passo con il computer o viceversa.
  • Segnalazione: interruzione ( intr, Ctrl+ C), chiusura forzata ( quit, Ctrl+ \), sospensione ( Ctrl+ Z).

Alcuni sistemi, incluso Linux, estendono tale elenco, ma non ne ho mai visto uno che includesse lo sfondo. Si noti che richiederebbe supporto sia nel driver del terminale nel kernel, sia nell'emulatore di terminale. Quindi devi accontentarti della sospensione, che invia al lavoro in primo piano un segnale SIGTSTP . Ciò innesca un SIGCHLD nel processo padre del leader del lavoro in primo piano, che di solito è la shell. Quando la shell ha ricevuto SIGCHLD, chiama waitpidper capire perché è stata notificata e, al rilevamento di un processo in background sospeso, visualizza una notifica (ad es. [1] + 12345 suspended mycommand) E un nuovo prompt.

È possibile programmare la shell per inviare un SIGCONTsegnale al lavoro in primo piano. Non credo che zsh abbia un gancio per questo, avresti bisogno di patchare il codice sorgente. E non c'è modo per zsh di sapere se intendevi veramente interrompere il programma (oops, questo programma potrebbe fare la cosa sbagliata, lasciami sospenderlo mentre lo risolvo) o metterlo in background.


Quello che faccio è impostare la sequenza di tasti Ctrl+ Zin zsh per mettere in background il lavoro corrente ( %%). In questo modo, posso inviare il lavoro in primo piano sullo sfondo premendo Ctrl+ Z Ctrl+ Z. Mentre ci sono, faccio Ctrl+ Zfare qualcos'altro utile quando la riga di input corrente non è vuota (quindi non sono appena tornata da un sottoprocesso): "sospendi" la riga di input corrente, permettendomi di digitare un altro comando , dopo di che la linea interrotta viene reinserita nel buffer di input.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z

Gilles, questa è una risposta incredibilmente completa, istruttiva e ponderata che non potevo aspettarmi di ottenere! Grazie mille!
Evgeniy Dolzhenko,

2

^ z ^ z come zsh sopra è possibile in bash, anche se è un po 'kludgy e non lo eseguo da molto:

  • Nel tuo .inputrc includi la mappatura "\C-z": "bg\n"
  • Nella variabile bash PS0 includere `$ (stty susp ^ z) '
  • Nella variabile bash PROMPT_COMMAND includere 'stty susp ^ @'

così ^ z per suspend viene attivato quando viene eseguito un comando, quindi disattivato per il prompt di bash.


1

Quindi ho trovato la soluzione, non esattamente quello che voglio ma dannatamente vicino da qui /superuser//a/161922/35223

Su una riga di comando vuota viene eseguito bg (in modo che Ctrl + Z Ctrl + Z sospenda un programma e lo riprenda immediatamente in background).


Noterò che questo richiede zsh; non è supportato in bash. (fuori dagli schemi, comunque)
Kevin M,

@KevinM Puoi scrivere una funzione analoga in bash (almeno la versione di base che effettua la Ctrl+Zchiamata bg, non sono sicuro di rilevare una linea di input non vuota).
Gilles 'SO- smetti di essere malvagio' il

0

Sono questi comandi che volevi eseguire inizialmente in primo piano e quindi passare allo sfondo? Non so se esiste un modo più semplice per farlo. Ma se vuoi eseguire comandi che saranno in background per cominciare, puoi semplicemente aggiungere una e commerciale alla fine della riga. ad esempio, ping google.com &inizierà il ping in background; non sarai in grado di interagire con esso se non digiti fg.


1
Grazie, il problema è che a volte non hai idea di quanto tempo impiegherebbe il comando, quindi corri in modo interattivo e ti rendi conto che è meglio lasciarlo continuare in background. La risposta accettata fa miracoli per me, usandola quotidianamente!
Evgeniy Dolzhenko,

Grazie per la risposta. La risposta accettata è piuttosto ordinata!
octern
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.