Metti un processo iniziato con! sullo sfondo


8

Se lo faccio dalla shell:

$ sleep 100

Posso farlo andare in secondo piano facendo:

^Z
$ bg

E poi continua a usare la mia shell. Puoi ottenere lo stesso effetto aggiungendo &a alla fine del comando, ma spesso lo dimentico.

In Vim, faccio spesso:

:!sleep 100

E anche qui, spesso dimentico di aggiungere il &. Posso mettere questo processo in background e continuare a usare Vim come nella shell?


1
Per evitare di dimenticare di nuovo, potresti chiedere a Vim di aggiungere &ogni volta: :nnoremap :! :!&<Left>... Ma ovviamente, a volte non vorrai il &, e dovrai premere <Del> per rimuoverlo.
joeytwiddle,

@joeytwiddle Questa è una buona idea e suona come qualcosa che potresti scrivere come una risposta, invece di un semplice commento :-)
Martin Tournoij

Risposte:


5

Come <C-z>sospenderà Vim stesso, non solo il comando di shell lanciato, che non funzionerà.

Quello che vorrei fare è interrompere il comando di lunga durata con <C-c>, quindi riavviare lo stesso comando in background tramite

:!! &

(Il :!!comando è utile per richiamare qui il precedente comando esterno; è anche possibile utilizzare la cronologia dei comandi Ex tramite <Up>.)


1
Questo è esattamente il flusso di lavoro che spero di migliorare. Il problema è che devi chiudere qualunque cosa tu abbia iniziato ...
Martin Tournoij,

1

È possibile inserire il comando in uno script shell che si sfondi da solo. I contenuti, ad esempio, potrebbero essere:

#!/bin/sh
sleep 100 &

3
Che non sarebbe molto utile una volta che il comando è già stato avviato.
Muru,

Voglio dire che si potrebbe eseguire lo script della shell invece del comando lento. Avere lo stesso sfondo evita la necessità di ricordare di averlo fatto in fase di esecuzione. Immagino di non capire molto bene il caso d'uso. Se è lo stesso comando che continuo a dimenticare in background, utilizzerei lo script della shell. Se ciò accade con comandi arbitrari, prenderei in considerazione l'abitudine di passare a una shell reale per farlo.
Jon Carter,

Uso tmuxdi default, ma il problema è che la mia sessione Vim (con file aperti e simili) è ancora inutile. Ho potuto passare a un altro riquadro, ed eseguire il mio script lì, ma che sono molte più azioni rispetto :!gitk %ad esempio ... La cosa con l'utilizzo di script è che avrei dovuto pre-creare molti di questi script per ogni comando possibile. Forse non è una cattiva idea per alcuni dei comandi più usati (come gitk& mupdf).
Martin Tournoij,

1

Normalmente quando viene avviato un processo, non si ha molto controllo su di esso oltre a terminarlo ( Ctrl+ c) o sospenderlo ( Ctrl+ z, ma includendo il processo padre).

Tuttavia, a seconda del tipo di processo e del sistema operativo, ecco alcuni trucchi che puoi provare:

  • L'invio SIGTSTPo SIGSTOPinterromperà il processo (lo stesso segnale inviato da Ctrl+ z) e SIGCONTcontinuerà (riprenderà) il processo. Il test con sleepnon funziona, quindi devi testarlo con un software specifico su come gestisce i segnali. Per esempio

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

    SIGSTOP stop process stop (non può essere catturato o ignorato)

    Segnale di arresto del processo di arresto SIGTSTP generato dalla tastiera

  • Invio SIGHUPal processo. Per impostazione predefinita, questo segnale termina il processo, tuttavia se il processo implementa il segnale SIGHUP, dovrebbe staccarsi dal controllo di tty e rieseguirlo in background con un nuovo ID di processo (di solito viene utilizzato con i demoni). Sfortunatamente molte applicazioni non lo gestiscono correttamente e semplicemente muoiono (incluso sleep). Per esempio

    killall -SIGHUP sleep
    

    SIGHUP termina il blocco della linea terminale di processo

  • Altre soluzioni potrebbero utilizzare strumenti come retty(ricollegare a una pseudo-tty), detach(scollega un processo dal terminale), nohup( disconnette il processo dal terminale ) o gdb(collegarsi al processo esistente -pe chiudere i descrittori di file come tty, esempio simile ).

Per maggiori informazioni, controlla: Controllo lavori (Unix) - Implementazione su Wikipedia.

Vedi anche: man killo man sigaction.


È strano che questo funzioni per te, non dovrebbe. STOP / CONT dovrebbe semplicemente mettere in pausa e riprendere il processo, niente di più. Non funziona qui, in console vim o gvim.
derobert,

1

Nota : questa risposta sembra funzionare solo con le shell tcshe fish. Ho anche provato bash, dash, mksh, e zsh, e non ci lavoro; Io non so perché, perché se faccio le stesse azioni di questi gusci senza Vim, si fa il lavoro come previsto ... ( :!comandi vengono eseguiti anche se il guscio).

Mi capita di usare tcsh, quindi funziona per me ...

Puoi usare :set shell=/bin/tcshper impostare la tua shell; questo è globale, però. Quindi usalo solo se pensi che questa sia una funzione molto importante :-)


^Zinviare un SIGTSTPsegnale, è possibile inviare questo segnale con kill, quindi utilizzare SIGCONTper continuare (riprendere) il processo. Questo distaccerà il processo da Vim.

Poiché è difficile mostrarlo con questo sleep(come fai a sapere che ha continuato l'esecuzione?), Userò gitkcome esempio (ma qualsiasi programma GUI lo farà):

Ad esempio in Vim:

:!gitk %

E poi in un altro terminale:

$ 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

Ovviamente puoi anche usare killall, oppure pkill; per esempio:

$ killall -TSTP wish
$ killall -CONST wish

È necessario aprire un altro terminale per questo, che non è l'ideale, ma ti consentirà di continuare a utilizzare sia il tuo Vim che il tuo processo esterno.

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.