Poner un proceso comenzó con! en el fondo

8

Si hago esto desde el shell:

$ sleep 100

Puedo hacer que pase al fondo haciendo:

^Z
$ bg

Y luego continúo usando mi caparazón. Puede obtener el mismo efecto agregando un &al final del comando, pero a menudo lo olvido.

En Vim, a menudo hago:

:!sleep 100

Y aquí también, a menudo me olvido de agregar el &. ¿Puedo poner este proceso en segundo plano y continuar usando Vim como en el shell?

Martin Tournoij
fuente
1
Para evitar volver a olvidar, puede pedirle a Vim que agregue &cada vez: :nnoremap :! :!&<Left>... Pero, por supuesto, a veces no querrá el &, y tendrá que presionar <Del> para eliminarlo.
joeytwiddle
@joeytwiddle Esa es una buena idea, y suena como algo que podrías escribir como respuesta, en lugar de solo un comentario :-)
Martin Tournoij

Respuestas:

5

Como <C-z>suspenderá a Vim, no solo el comando de shell lanzado, eso no funcionará.

Lo que haría sería cancelar el comando de ejecución prolongada y <C-c>luego volver a iniciar el mismo comando en segundo plano a través de

:!! &

(El :!!comando es útil para recuperar el comando externo anterior aquí; también puede usar el historial de comandos Ex a través de <Up>).

Ingo Karkat
fuente
1
Este es exactamente el flujo de trabajo que espero mejorar. El problema es que debes cerrar lo que empezaste ...
Martin Tournoij
1

Puede poner el comando en un script de shell que se ejecute en segundo plano. Los contenidos, por ejemplo, pueden ser:

#!/bin/sh
sleep 100 &
Jon Carter
fuente
3
Lo cual sería de poca utilidad una vez que el comando ya se haya iniciado.
muru
Quiero decir que uno podría ejecutar el script de shell en lugar del comando lento. Tener un fondo en sí mismo evita la necesidad de recordar hacerlo en tiempo de ejecución. Supongo que no entiendo muy bien el caso de uso. Si es el mismo comando que sigo olvidando en segundo plano, usaría el script de shell. Si esto sucede con comandos arbitrarios, consideraría la costumbre de cambiar a un shell real para hacerlo.
Jon Carter
Lo uso tmuxde forma predeterminada, pero el problema es que mi sesión de Vim (con archivos abiertos y demás) sigue siendo inútil. Yo podría cambiar a otro panel, y corro mi guión, pero que son mucho más acciones que :!gitk %por ejemplo ... Lo que pasa con el uso de scripts es que tendría que crear previamente muchas de estas secuencias de comandos para cada orden posible. Quizás no sea una mala idea para algunos de los comandos más utilizados (como gitk& mupdf).
Martin Tournoij
1

Normalmente, cuando se inicia un proceso, no tiene mucho control sobre él más que terminarlo ( Ctrl+ c) o suspenderlo ( Ctrl+ z, pero incluido el proceso padre).

Sin embargo, dependiendo del tipo de proceso y el sistema operativo, aquí hay algunos trucos que puede probar:

  • Enviar SIGTSTPo SIGSTOPdetendrá el proceso (la misma señal enviada por Ctrl+ z) y SIGCONTcontinuará (reanudará) el proceso. La prueba con sleepno funciona, por lo que debe probarla con un software específico sobre cómo maneja las señales. P.ej

    killall -SIGSTOP sleep
    killall -SIGTSTP sleep
    kill -SIGTSTP PID
    

    SIGSTOP detener proceso detener (no puede ser atrapado o ignorado)

    Señal de parada del proceso de parada SIGTSTP generada desde el teclado

  • Envío SIGHUPal proceso. De forma predeterminada, esta señal finaliza el proceso, sin embargo, si el proceso implementa la señal SIGHUP, debería separarse del control de tty y volver a ejecutarse en segundo plano con una nueva identificación de proceso (generalmente se usa con daemons). Desafortunadamente, muchas aplicaciones no lo manejan correctamente y simplemente mueren (incluido sleep). P.ej

    killall -SIGHUP sleep
    

    SIGHUP terminar la línea de terminales del proceso

  • Otra solución podría usar herramientas como retty(volver a conectar a un pseudo-tty), detach( desconecta un proceso del terminal), nohup( desconecta el proceso del terminal ) o gdb(adjunta al proceso existente -py cierra sus descriptores de archivo como tty, ejemplo similar )

Para obtener más información, consulte: Control de trabajos (Unix): implementación en Wikipedia.

Ver también: man killo man sigaction.

kenorb
fuente
Es extraño que esto funcione para ti, no debería. STOP / CONT debería simplemente pausar y reanudar el proceso, nada más. No funciona aquí, ni en la consola vim ni en gvim.
derobert
1

Nota : Esta respuesta sólo parece trabajar con el tcshy fishconchas. Yo también trató bash, dash, mksh, y zsh, y no trabajo allí; No estoy seguro de por qué, porque si hago las mismas acciones de estas conchas sin Vim, que hace el trabajo como se esperaba ... ( :!comandos se ejecutan a pesar de la cáscara).

Yo uso tcsh, así que funciona para mí ...

Puede usar :set shell=/bin/tcshpara configurar su shell; Sin embargo, esto es global. Así que solo úsalo si crees que esta es una característica muy importante :-)


^Zenviar una SIGTSTPseñal, puede enviar esta señal con kill, y luego usar SIGCONTpara continuar (reanudar) el proceso. Esto separará el proceso de Vim.

Debido a que es difícil de mostrar con esto sleep(¿cómo sabe que tiene una ejecución continua?), Lo usaré gitkcomo ejemplo (pero cualquier programa GUI funcionará):

Por ejemplo en Vim:

:!gitk %

Y luego en otra terminal:

$ ps ax | grep gitk
30105 pts/10   S+     0:00 -bin/tcsh -c gitk
30108 pts/10   Sl+    0:00 wish /sbin/gitk --

$ kill -TSTP 30108
$ kill -CONT 30108

Por supuesto, también puede usar killall, o pkill; por ejemplo:

$ killall -TSTP wish
$ killall -CONST wish

Necesitas abrir otro terminal para esto, lo cual no es ideal, pero te permitirá continuar usando tanto tu Vim como tu proceso externo.

Martin Tournoij
fuente