Parfois, je dois écrire du texte, puis rediriger ce texte dans une autre commande. Mon flux de travail habituel ressemble à ceci:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Je trouve cela lourd et cherchant à apprendre les scripts bash, je voudrais rendre le processus beaucoup plus simple en écrivant une commande qui déclenche l'ouverture d'un éditeur et lorsque l'éditeur se ferme, redirige la sortie de l'éditeur vers stdout. Ensuite, je serais en mesure d'exécuter la commande en tant que quickedit | pandoc -o file.pdf
.
Je ne sais pas comment cela fonctionnerait. J'ai déjà écrit une fonction pour automatiser cela en suivant le flux de travail exact ci-dessus et quelques ajouts. Il génère une chaîne aléatoire pour agir comme un nom de fichier et la transmet à vim lorsque la fonction est invoquée. Lorsque l'utilisateur quitte vim en enregistrant le fichier, la fonction imprime le fichier sur la console, puis supprime le fichier.
function quickedit {
filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
vim $filename
cat $filename
rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal
Le problème que j'ai rapidement rencontré est que lorsque je fais quelque chose comme quickedit | command
vim lui-même, il ne peut pas être utilisé comme éditeur car toutes les sorties sont limitées au tuyau.
Je me demande s'il y a des solutions à cela, afin que je puisse diriger la sortie de ma quickedit
fonction. L'alternative sous-optimale est de lancer un éditeur séparé, par exemple un texte sublime, mais je veux vraiment rester dans le terminal.
:w !pandoc -o file.pdf
? (Remarque: l'espace entrew
et!
est essentiel.)mktemp
plutôt que de le réinventer de manière non sécurisée.Réponses:
vipe
est un programme pour éditer des pipelines:Vous obtenez un éditeur avec la sortie complète de
command1
, et lorsque vous quittez, le contenu est transmiscommand2
via le canal.Dans ce cas, il n'y a pas
command1
. Donc, vous pourriez faire:Ou:
vipe
reprend les variablesEDITOR
etVISUAL
, vous pouvez donc les utiliser pour ouvrir Vim.Si vous ne l'avez pas installé,
vipe
est disponible dans lemoreutils
package;sudo apt-get install moreutils
, ou quel que soit l'équivalent de votre saveur.la source
moreutils
est disponible dans Homebrew.moreutils
est disponible pour être installé via pkg (8) .Vous pouvez le faire depuis Vim:
Ou même écrivez le tampon dans un pipeline complexe:
Et puis vous pouvez quitter Vim sans enregistrer:
Cependant, compte tenu de votre cas d'utilisation spécifique, il existe probablement une meilleure solution en utilisant
vi
comme éditeur de ligne de commande. En supposant que vous utilisezbash
:Cela définit vos raccourcis clavier sur
vi
. Ainsi , vous pouvez modifier vos commandes à droite sur la ligne de commande avec basevi
raccourcis clavier en appuyant sur<Esc>
, puis en tapant desvi
commandes telles quex
,cw
, etc. (Vous pouvez revenir en mode d'insertion en appuyant suri
.)Encore mieux et plus pertinent pour cette question, vous pouvez ouvrir Vim pour créer directement le contenu de votre ligne de commande. Tapez simplement
<Esc>v
et vous obtiendrez un tampon Vim vide. Lorsque vous enregistrez et quittez, c'est la commande sur votre ligne de commande et il est immédiatement exécuté. C'est beaucoup plus flexible que l'édition directe sur la ligne de commande car vous pouvez écrire un mini-script entier si vous le souhaitez.Ainsi, par exemple, si vous souhaitez écrire du texte délicat et le canaliser immédiatement dans pandoc, vous pouvez simplement taper:
Modifiez ensuite le tampon Vim jusqu'à ce que vous ayez quelque chose comme:
Ensuite, enregistrez et quittez (avec
:x
) et le tout sera exécuté comme une commande shell.Il sera également disponible dans l'historique des commandes de votre shell.
la source
EDITOR
variable d'environnement survim
et en appuyant surCtrl-X
puis enCtrl-E
modifiant la ligne de commande.Exécution dans un pipeline
Essayer:
La clé est que, pour pouvoir utiliser
vim
normalement,vim
stdout doit être le terminal. Nous accomplissons cela ici avec la redirection>/dev/tty
.Pour des raisons de sécurité, j'ai placé le fichier temporaire dans le répertoire personnel de l'utilisateur. Pour en savoir plus à ce sujet, consultez la question 062 de la FAQ de Greg . Cela élimine le besoin d'utiliser un nom de fichier obscur.
Exemple:
Lorsqu'il
vim
s'ouvre, je tapeThis function succeeded.
et enregistre le fichier. Le résultat à l'écran ressemble à:Même si la sortie de
quickedit
est redirigée vers un pipeline,vim
fonctionne toujours normalement car nous lui avons donné un accès direct à/dev/tty
.Exécuter un programme depuis vim
Comme je l'ai mentionné dans les commentaires, vim peut diriger un fichier vers une commande. Depuis vim, par exemple, exécutez la commande
:w !pandoc -o file.pdf
(Remarque: l'espace entre w et! Est essentiel).la source
trap '...' exit
échoue maistrap '...' EXIT
semble fonctionner. Je ne sais pas grand chose sur le piégeage, mais mon approche générale pour les fichiers temporaires est d'utilisermktmp [--suffix=...]
. En outre,vim <outfile> -c '...' >/dev/tty
s'exécute normalement jusqu'à ce que le fichier soit chargé, puis exécute la chaîne de commandes donnée, y compris:wq
si vous souhaitez ignorer la phase d'édition. J'ai également utiliséset | grep -a EXIT
et trouvésignals=(EXIT ... DEBUG)
.Assurez-vous qu'il
vim
est défini comme votre éditeur par défaut (par exempleexport EDITOR=vim
dans votre.bash_profile
ou.bashrc
. Ensuite, à toute invite, vous pouvez taper Ctrl- Xsuivi de Ctrl- E. Cela ouvrira votre ligne de commande actuelle dans votre éditeur configuré (par exemplevim
). Faites vos modifications, enregistrez et exit, et la commande sera exécutée comme si vous l'aviez tapée sur la ligne de commande, y compris les pipelines et autres.la source