Comment puis-je faire Ctrl-Z et bg en une seule touche pour faire continuer le processus en arrière-plan?

25

Je suis ce schéma de suspension de la tâche, puis de la laisser continuer trop souvent avec la Ctrl-Z bgséquence.

Je me demandais s'il y avait un moyen de compresser cela en une seule touche?

Ma coquille est zsh

Evgeniy Dolzhenko
la source
Je veux dire que c'est probablement codé en dur. Mais je ne suis pas à 100%
Chad Harrison
Bien sûr, mais j'ai trouvé la solution élégante, merci superuser.com/a/161922/35223
Evgeniy Dolzhenko

Réponses:

24

La séquence Ctrl+ Zest gérée par le terminal, pas par le shell. (Contexte utile: Quelle est la différence exacte entre un 'terminal', un 'shell', un 'tty' et une 'console'? )

Seul un petit ensemble de fonctions non extensibles peut être lié à une clé dans un terminal . Vous pouvez personnaliser les touches liées à ces fonctions mais pas ajouter une autre fonction. Ces fonctions se répartissent en trois catégories:

  • Édition en ligne de commande dans des programmes qui ne fournissent pas le leur (mode canonique, également appelé mode cuit (par opposition au mode brut), que vous utiliserez rarement en pratique): fin de fichier ( eof, Ctrl+ D), fin de ligne ( eol, Ctrl+ M), effacer le caractère à gauche ( erase, Ctrl+ H), effacer le mot à gauche ( werase, Ctrl+ W), effacer la ligne ( kill, Ctrl+ U).
  • Contrôle de débit manuel: stop( Ctrl+ S), start( Ctrl+ Q). Utile uniquement sur les anciens terminaux série qui perdaient des caractères lorsque le terminal ne pouvait pas suivre l'ordinateur ou vice versa.
  • Signalisation: interrompre ( intr, Ctrl+ C), forcer la fermeture ( quit, Ctrl+ \), suspendre ( Ctrl+ Z).

Certains systèmes, y compris Linux, étendent cette liste, mais je n'en ai jamais vu un qui incluait des antécédents. Notez qu'il prendrait en charge à la fois le pilote de terminal dans le noyau et l'émulateur de terminal. Vous devez donc vous contenter de la suspension, qui envoie au travail de premier plan un signal SIGTSTP . Cela déclenche un SIGCHLD dans le processus parent du leader du travail de premier plan, qui est généralement le shell. Lorsque le shell a reçu SIGCHLD, il appelle waitpidpour comprendre pourquoi il a été notifié et, lorsqu'il détecte qu'un travail d'arrière-plan a été suspendu, il affiche une notification (par exemple [1] + 12345 suspended mycommand) et une nouvelle invite.

Vous pouvez programmer le shell pour envoyer un SIGCONTsignal au travail de premier plan. Je ne pense pas que zsh ait un crochet pour cela, vous auriez besoin de patcher le code source. Et il n'y a aucun moyen pour zsh de savoir si vous vouliez vraiment interrompre le programme (oups, ce programme peut faire la mauvaise chose, permettez-moi de le suspendre pendant que je le trie) ou de le mettre en arrière-plan.


Ce que je fais est de définir la séquence de touches Ctrl+ Zdans zsh pour mettre en arrière-plan le travail en cours ( %%). De cette façon, je peux envoyer le travail de premier plan à l'arrière-plan en appuyant sur Ctrl+ Z Ctrl+ Z. Pendant que j'y suis, je fais Ctrl+ Zfaire autre chose d'utile quand la ligne d'entrée courante n'est pas vide (donc je ne viens pas juste de revenir d'un sous-processus): "suspendre" la ligne d'entrée courante, me permettant de taper une autre commande , après quoi la ligne interrompue est repoussée dans le tampon d'entrée.

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 'SO- arrête d'être méchant'
la source
Gilles, c'est une réponse incroyablement complète, éducative et réfléchie à laquelle je ne pouvais pas m'attendre! Merci beaucoup!
Evgeniy Dolzhenko
2

^ z ^ z comme zsh ci-dessus est possible en bash, bien que ce soit un peu délicat et je n'ai pas fait ça depuis longtemps:

  • Dans votre .inputrc, incluez le mappage "\C-z": "bg\n"
  • Dans la variable bash PS0, incluez `$ (stty susp ^ z) '
  • Dans la variable bash PROMPT_COMMAND, incluez 'stty susp ^ @'

donc ^ z pour la suspension est activé lors de l'exécution d'une commande, puis désactivé pour l'invite bash.

JohnLittle
la source
1

J'ai donc trouvé la solution, pas exactement ce que je veux mais sacrément proche d'ici /superuser//a/161922/35223

Sur une ligne de commande vide exécute bg (de sorte que Ctrl + Z Ctrl + Z suspend un programme et le reprend immédiatement en arrière-plan).

Evgeniy Dolzhenko
la source
Je noterai que cela nécessite zsh; il n'est pas pris en charge dans bash. (hors de la boîte, de toute façon)
Kevin M
@KevinM Vous pouvez écrire une fonction analogue en bash (au moins la version de base faisant Ctrl+Zappel bg, je ne suis pas sûr de détecter une ligne d'entrée non vide).
Gilles 'SO- arrête d'être méchant'
0

Ces commandes que vous vouliez exécuter au premier plan sont-elles initialement, puis basculez-vous en arrière-plan? Je ne sais pas s'il existe un moyen plus simple de le faire. Mais si vous souhaitez exécuter des commandes qui seront en arrière-plan pour commencer, vous pouvez simplement ajouter une esperluette à la fin de la ligne. par exemple, ping google.com &va commencer à cingler en arrière-plan; vous ne pourrez pas interagir avec lui à moins de taper fg.

octern
la source
1
Merci, le problème est que, parfois, vous n'avez pas une idée du temps d'exécution de la commande, vous exécutez donc de manière interactive, puis vous réalisez qu'il vaut mieux la laisser continuer en arrière-plan. La réponse acceptée fait des merveilles pour moi, en l'utilisant quotidiennement!
Evgeniy Dolzhenko
Merci pour la réponse. La réponse acceptée est assez soignée!
octern