Mettez un processus commencé avec! en arrière-plan

8

Si je fais cela depuis le shell:

$ sleep 100

Je peux le faire passer à l'arrière-plan en faisant:

^Z
$ bg

Et puis continuez à utiliser ma coquille. Vous pouvez obtenir le même effet en ajoutant un &à la fin de la commande, mais j'oublie souvent cela.

A Vim, je fais souvent:

:!sleep 100

Et là aussi, j'oublie souvent d'ajouter le &. Puis-je mettre ce processus en arrière-plan et continuer à utiliser Vim comme dans le shell?

Martin Tournoij
la source
1
Pour éviter d'oublier à nouveau, vous pouvez demander à Vim d'ajouter à &chaque fois: :nnoremap :! :!&<Left>... Mais bien sûr, parfois vous ne voudrez pas de &, et devrez appuyer sur <Del> pour le supprimer.
joeytwiddle
@joeytwiddle C'est une bonne idée, et cela ressemble à quelque chose que vous pourriez écrire comme réponse, au lieu d'un simple commentaire :-)
Martin Tournoij

Réponses:

5

Comme <C-z>va suspendre Vim lui-même, pas seulement la commande shell lancée, cela ne fonctionnera pas.

Ce que je ferais, c'est abandonner la commande de longue durée avec <C-c>, puis relancer la même commande en arrière-plan via

:!! &

(La :!!commande est pratique pour rappeler la commande externe précédente ici; vous pouvez également utiliser l'historique des commandes Ex via <Up>.)

Ingo Karkat
la source
1
C'est exactement le flux de travail que j'espère améliorer. Le problème est que vous devez fermer tout ce que vous avez commencé ...
Martin Tournoij
1

Vous pouvez placer la commande dans un script shell qui se déroule en arrière-plan. Le contenu, par exemple, pourrait être:

#!/bin/sh
sleep 100 &
Jon Carter
la source
3
Ce qui ne serait pas très utile une fois la commande lancée.
muru le
Je veux dire que l'on pourrait exécuter le script shell au lieu de la commande lente. Le fait de l'avoir lui-même évite d'avoir à se souvenir de le faire au moment de l'exécution. Je suppose que je ne comprends pas très bien le cas d'utilisation. Si c'est la même commande que j'oublie en arrière-plan, j'utiliserais le script shell. Si cela se produit avec des commandes arbitraires, j'envisagerais de prendre l'habitude de passer à un véritable shell pour le faire.
Jon Carter
J'utilise tmuxpar défaut, mais le problème est que ma session Vim (avec des fichiers ouverts et autres) est toujours inutile. Je pourrais passer à un autre volet et y exécuter mon script, mais ce sont beaucoup plus d'actions que :!gitk %par exemple ... Le problème avec l'utilisation de scripts est que je devrais pré-créer un grand nombre de ces scripts pour chaque commande possible. Ce n'est peut-être pas une mauvaise idée pour certaines des commandes les plus utilisées (telles que gitk& mupdf).
Martin Tournoij
1

Normalement, lorsqu'un processus est démarré, vous n'avez pas beaucoup de contrôle sur lui, à part le terminer ( Ctrl+ c) ou le suspendre ( Ctrl+ z, mais en incluant le processus parent).

Cependant, selon le type de processus et le système d'exploitation, voici quelques astuces que vous pouvez essayer:

  • L'envoi SIGTSTPou SIGSTOParrêtera le processus (le même signal envoyé par Ctrl+ z) et SIGCONTcontinuera (reprendra) le processus. Le test avec sleepne fonctionne pas, vous devez donc le tester avec un logiciel spécifique pour savoir comment il gère les signaux. Par exemple

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

    Arrêt du processus d'arrêt SIGSTOP (ne peut pas être intercepté ou ignoré)

    Signal d'arrêt du processus d'arrêt SIGTSTP généré à partir du clavier

  • Envoi SIGHUPau processus. Par défaut, ce signal met fin au processus, mais si le processus implémente le signal SIGHUP, il doit se détacher du contrôle de tty et réexécuter en arrière-plan avec un nouvel identifiant de processus (généralement utilisé avec les démons). Malheureusement, de nombreuses applications ne le gèrent pas correctement et meurent simplement (y compris sleep). Par exemple

    killall -SIGHUP sleep
    

    SIGHUP terminer le raccrochage de la ligne de terminal du processus

  • Une autre solution pourrait utiliser des outils tels que retty(rattacher à un pseudo-tty), detach(détacher un processus du terminal), nohup( déconnecter le processus du terminal ) ou gdb(attacher au processus existant -pet fermer ses descripteurs de fichiers tels que tty, exemple similaire ).

Pour plus d'informations, consultez: Job control (Unix) - Implementation at Wikipedia.

Voir aussi: man killou man sigaction.

kenorb
la source
C'est bizarre que cela fonctionne pour vous - ça ne devrait pas. STOP / CONT devrait simplement mettre en pause et reprendre le processus, rien de plus. Cela ne fonctionne pas ici, dans la console vim ou gvim.
derobert
1

Remarque : Cette réponse ne semble fonctionner qu'avec les coquilles tcshet fish. J'ai aussi essayé bash, dash, mkshet zsh, et il ne pas y travailler; Je ne sais pas pourquoi, parce que si je fais les mêmes actions de ces coquilles sans Vim, il ne fonctionne comme prévu ... ( :!commandes sont exécutées si le shell).

Il se trouve que j'utilise tcsh, donc ça marche pour moi ...

Vous pouvez utiliser :set shell=/bin/tcshpour définir votre shell; c'est mondial, cependant. Donc, ne l'utilisez que si vous pensez que c'est une fonctionnalité très importante :-)


^Zenvoyer un SIGTSTPsignal, vous pouvez envoyer ce signal avec kill, puis utiliser SIGCONTpour continuer (reprendre) le processus. Cela détachera le processus de Vim.

Parce qu'il est difficile de montrer avec cela sleep(comment savez-vous qu'il a continué son exécution?), Je vais utiliser gitkcomme exemple (mais tout programme GUI fera l'affaire):

Par exemple dans Vim:

:!gitk %

Et puis dans un autre 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

Vous pouvez bien sûr également utiliser killall, ou pkill; par exemple:

$ killall -TSTP wish
$ killall -CONST wish

Pour cela, vous devez ouvrir un autre terminal, ce qui n'est pas idéal, mais cela vous permettra de continuer à utiliser à la fois votre Vim et votre processus externe.

Martin Tournoij
la source