¿Cómo puedo hacer Ctrl-Z y bg con solo presionar una tecla para que el proceso continúe en segundo plano?

25

Sigo este patrón de suspender la tarea y luego dejar que continúe con demasiada frecuencia con la Ctrl-Z bgsecuencia.

Me preguntaba ¿hay alguna forma de comprimir eso con solo presionar una tecla?

Mi caparazón es zsh

Evgeniy Dolzhenko
fuente
Quiero decir que probablemente esté codificado. Pero no estoy 100%
Chad Harrison
Claro que lo es, pero he encontrado la solución elegante, gracias superuser.com/a/161922/35223~~V~~singular~~2nd
Evgeniy Dolzhenko

Respuestas:

24

La secuencia Ctrl+ Zes manejada por el terminal, no por el shell. (Antecedentes útiles: ¿Cuál es la diferencia exacta entre un 'terminal', un 'shell', un 'tty' y una 'consola'? )

Solo un pequeño conjunto de funciones no extensible puede vincularse a una tecla en un terminal . Puede personalizar las teclas vinculadas a estas funciones pero no agregar otra función. Estas funciones se dividen en tres categorías:

  • Edición de línea de comando en programas que no proporcionan el suyo (modo canónico, también llamado modo cocinado (por oposición con el modo sin procesar), que rara vez usará en la práctica): fin de archivo ( eof, Ctrl+ D), fin de línea ( eol, Ctrl+ M), borrar carácter a la izquierda ( erase, Ctrl+ H), borrar palabra a la izquierda ( werase, Ctrl+ W), borrar línea ( kill, Ctrl+ U).
  • Control de flujo manual: stop( Ctrl+ S), start( Ctrl+ Q). Solo es útil en terminales seriales antiguas que soltaron caracteres cuando el terminal no podía seguir el ritmo de la computadora o viceversa.
  • Señalización: interrumpir ( intr, Ctrl+ C), forzar el abandono ( quit, Ctrl+ \), suspender ( Ctrl+ Z).

Algunos sistemas, incluido Linux, amplían esa lista, pero nunca he visto uno que incluya el fondo. Tenga en cuenta que necesitaría soporte tanto en el controlador de terminal en el kernel como en el emulador de terminal. Entonces tiene que conformarse con suspender, que envía al trabajo en primer plano una señal SIGTSTP . Esto desencadena un SIGCHLD en el proceso principal del líder del trabajo en primer plano, que generalmente es el shell. Cuando el shell recibió SIGCHLD, llama waitpidpara averiguar por qué fue notificado, y al detectar que se suspendió un trabajo en segundo plano, muestra una notificación (por ejemplo [1] + 12345 suspended mycommand) y una nueva solicitud.

Puede programar el shell para enviar una SIGCONTseñal al trabajo en primer plano. No creo que zsh tenga un gancho para eso, tendrías que parchear el código fuente. Y no hay forma de que zsh sepa si realmente quisiste interrumpir el programa (vaya, este programa puede estar haciendo algo incorrecto, déjame suspenderlo mientras lo soluciono) o ponerlo en segundo plano.


Lo que hago es establecer la secuencia de teclas Ctrl+ Zen zsh para poner en segundo plano el trabajo actual ( %%). De esa manera, puedo enviar el trabajo en primer plano al fondo presionando Ctrl+ Z Ctrl+ Z. Mientras estoy en ello, hago Ctrl+ Zhacer algo más útil cuando la línea de entrada actual no está vacía (por lo que no acabo de regresar de un subproceso): "suspender" la línea de entrada actual, lo que me permite escribir otro comando , después de lo cual la línea interrumpida se empuja hacia el búfer de entrada.

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- deja de ser malvado'
fuente
¡Gilles, esta es una respuesta increíblemente completa, educativa y reflexiva que no podía esperar obtener! Muchas gracias!
Evgeniy Dolzhenko
2

^ z ^ z como zsh anterior es posible en bash, aunque es un poco torpe y no he ejecutado esto por mucho tiempo:

  • En su .inputrc incluya el mapeo "\C-z": "bg\n"
  • En la variable bash de PS0 incluye `$ (stty susp ^ z) '
  • En la variable bash PROMPT_COMMAND incluye 'stty susp ^ @'

entonces ^ z para suspender se activa cuando se ejecuta un comando, luego se desactiva para el indicador de bash.

JohnLittle
fuente
1

Entonces encontré la solución, no exactamente lo que quiero, pero muy cerca de aquí /superuser//a/161922/35223

En una línea de comando vacía se ejecuta bg (de modo que Ctrl + Z Ctrl + Z suspende un programa y lo reanuda inmediatamente en segundo plano).

Evgeniy Dolzhenko
fuente
Notaré que esto requiere zsh; No es compatible con bash. (fuera de la caja, de todos modos)
Kevin M
@KevinM Puede escribir una función análoga en bash (al menos la versión básica que hace la Ctrl+Zllamada bg, no estoy seguro de detectar una línea de entrada no vacía).
Gilles 'SO- deja de ser malvado'
0

¿Son estos comandos que quería ejecutar en primer plano inicialmente y luego cambiar a segundo plano? No sé si hay una manera más sencilla de hacerlo. Pero si desea ejecutar comandos que estarán en segundo plano para comenzar, simplemente puede agregar un ampersand al final de la línea. por ejemplo, ping google.com &comenzará a hacer ping en segundo plano; no podrá interactuar con él a menos que escriba fg.

octern
fuente
1
Gracias, el problema es que a veces no tienes una idea de cuánto tiempo llevará ejecutar el comando, por lo que corres de forma interactiva y luego te das cuenta de que es mejor dejar que continúe en segundo plano. ¡La respuesta aceptada funciona de maravilla para mí, usándola a diario!
Evgeniy Dolzhenko
Gracias por la respuesta. ¡La respuesta aceptada es bastante clara!
octern