Lors de l'appel de vim
à find | xargs
, procédez comme suit:
find . -name "*.txt" | xargs vim
vous recevez un avertissement à propos de
Input is not from a terminal
et un terminal avec un comportement à peu près cassé par la suite. Pourquoi donc?
Lorsque vous appelez un programme via xargs
, le stdin (entrée standard) du programme pointe sur /dev/null
. (Puisque xargs ne connait pas le original stdin, c'est la meilleure chose à faire.)
$ true | xargs filan -s 0 chrdev /dev/null 1 tty /dev/pts/1 2 tty /dev/pts/1 $ true | xargs ls -l /dev/fd/
Vim s'attend à ce que son stdin soit identique à son terminal de contrôle et exécute diverses opérations relatives au terminal ioctl est sur stdin directement. Lorsque cela est fait sur /dev/null
(ou tout descripteur de fichier non-tty), ces ioctls n'ont pas de sens et renvoient ENOTTY, ce qui est ignoré silencieusement.
À mon avis, une cause plus spécifique: Au démarrage, Vim lit et retient les anciens paramètres du terminal, puis les restaure à la sortie. Dans notre cas, lorsque les "anciens paramètres" sont demandés pour un descripteur de fichier non-tty, Vim reçoit toutes les valeurs vides et toutes les options désactivées, et définit négligemment la même chose sur votre terminal.
Vous pouvez le voir en exécutant vim < /dev/null
, en le quittant, puis en exécutant stty
, qui générera un grand nombre de <undef>
s. Sous Linux, exécuter stty sane
rendra le terminal utilisable à nouveau (bien que aura perdu des options telles que iutf8
, ce qui pourrait causer des ennuis mineurs. plus tard).
Vous pourriez considérer cela comme un bogue dans Vim, car il peut ouvrir /dev/tty
pour le contrôle terminal, mais ne le fait pas. (À un moment donné au cours du démarrage, Vim duplique son stderr sur stdin, ce qui lui permet de lire vos commandes d'entrée - à partir d'un fd ouvert en écriture - mais même cela n'est pas fait assez tôt.)
Suite à la réponse de grawity, xargs
points stdin
à /dev/null
De OSX/BSD man xargs
- o Rouvrez stdin en tant que/dev/tty dans le processus enfant avant d'exécuter la commande. Ceci est utile Si vous voulez que xargs exécute une application interactive.
Ainsi, la ligne de code suivante devrait fonctionner pour vous:
trouver . -name "* .txt" | xargs -o vim
Pour GNU man xargs
, il n'y a pas d'indicateur, mais nous pouvons explicitement passer dans/dev/tty pour résoudre le problème:
trouver . -name "* .txt" | xargs bash -c '</ dev/tty vim "$ @"' ignoreme
l'ignoreme est là pour prendre $ 0, donc $ @ est tous les arguments de xargs
Le moyen le plus simple:
vim $(find . -name "*foo*")
Cela devrait fonctionner correctement si vous utilisez l'option -exec sur find plutôt que de vous connecter à xargs.
find . -type f -name filename.txt -exec vi {} +
Utilisez GNU Parallel à la place:
find . -name "*.txt" | parallel -j1 --tty vim
Ou si vous voulez ouvrir tous les fichiers en une fois:
find . -name "*.txt" | parallel -Xj1 --tty vim
Il traite même correctement les noms de fichiers tels que:
My brother's 12" records.txt
Regardez la vidéo d'introduction pour en savoir plus: http://www.youtube.com/watch?v=OpaiGYxkSuQ
peut-être pas le meilleur mais voici le script que j'utilise (nommé vim-open
):
#!/usr/bin/env Ruby
require 'shellwords'
inputs = (ARGV + (STDIN.tty? ? [] : STDIN.to_a)).map(&:strip)
exec("</dev/tty vim #{inputs.flatten.shelljoin}")
fonctionnera avec vim-open a b c
et ls | vim-open
par exemple