J'ai parfois essayé d'invoquer Vim en utilisant xargs
, comme ceci:
find . -name '*.java' | xargs vim
… Quel genre d'œuvres:
Au lancement de Vim, je vois brièvement le flash d'avertissement suivant:
Vim: Warning: Input is not from a terminal
- L'édition fonctionne -
:files
énumère correctement tous les.java
fichiers comme prévu. - Je peux enregistrer et quitter.
Cependant, après avoir quitté Vim, mon terminal est bouché:
- Tout ce que je tape à l'invite du shell n'est pas répété.
- Les retours chariot n'apparaissent pas du tout et les sauts de ligne n'apparaissent que parfois.
Cela continue jusqu'à ce que j'émette une reset(1)
commande pour réinitialiser le terminal.
Est-ce un bug Vim, ou y a-t-il une explication plus satisfaisante pour expliquer pourquoi il interagit avec le terminal comme ça? Je l'ai vu se produire sur Vim jusqu'à la version 7.3 (la version ne semble pas avoir d'importance) sur Linux et divers Unices.
Je connais une solution de contournement, à savoir vim $(find . -name '*.java')
. D'autres solutions de contournement seraient les bienvenues, mais ce n'est pas ma principale question.
la source
xargs
utilise un mannequinstdin
qui ne peut pas être utilisé par Vim et fait une pause tout après.Réponses:
Cela se produit lorsque vim est appelé et qu'il est connecté à la sortie du pipeline précédent, au lieu du terminal et qu'il reçoit différentes entrées inattendues (comme des NUL). La même chose se produit lorsque vous exécutez:,
vim < /dev/null
donc lareset
commande dans ce cas est utile. Cela s'explique bien par la gravité du superutilisateur .Si vous utilisez
find
pour passer des noms de fichiers à modifier, vous n'avez pas besoinxargs
, utilisez simplement-exec
, par exemple:Si vous souhaitez utiliser
xargs
, sur Unix / macOS, vous devez utiliser un-o
paramètre, comme:ou:
Remarque: L'utilisation de
-print0
/-0
prendra en charge les noms de fichiers avec des espaces.find
+ BSDxargs
Sous Unix / macOS, vous pouvez essayer la solution de contournement suivante:
Vous pouvez également utiliser la syntaxe de substitution de commandes , par exemple:
Vous pouvez également utiliser GNU
parallel
au lieu dexargs
pour forcer l'allocation tty, par exemple:Remarque:
parallel
sous Unix / OSX ne fonctionnera pas car il a des paramètres différents et ne prend pas en charge tty.De nombreuses autres commandes populaires fournissent également une allocation pseudo-tty (comme
-t
dansssh
), alors vérifiez l'aide.Une autre suggestion serait d'utiliser:
ex
éditeur de ligne de commande pour analyser les données ou utiliser le mode Ex, pour plus de détails, voir:Comment éditer des fichiers de manière non interactive (par exemple dans un pipeline)?
vipe
(un tube de commande Vim)utilisez le script simple suivant:
En relation:
grep -l .. | xargs vim
génère un avertissement, pourquoi? [dup] chez unix SEla source
xargs
n'en a pas-J
. Cela semble être une option MacOS (BSD) qui n'est pas présente dans la version GNU.Solution de contournement: utilisez un tampon comme navigateur de système de fichiers
Utilisez la
vim -
commande pour lire une liste de chemins depuis stdin. Vim:help --
explique ceci: 1Vous pouvez ensuite utiliser gfou Ctrl-wCtrl-fpour naviguer vers le fichier dans le même tampon ou dans une nouvelle fenêtre divisée respectivement.
Solution de contournement: liste d'arguments
Un autre excellent moyen est d'utiliser la liste d'arguments de Vim. La
:argadd **/*.java
commande remplira la liste d'arguments de Vim avec tous les fichiers java trouvés dans le répertoire courant de manière récursive. Vous pouvez ensuite utiliser les touches:next
et:prev
pour vous déplacer entre les fichiers.1 Le premier
-
indique à Vim que vous souhaitez rechercher dans l'aide une option de ligne de commande, le second est en fait l'indicateur de ligne de commande que vous recherchez. Lisez:help help-context
pour plus d'astuces comme celle-ci.la source
De plus
reset
, vous pouvez essayer:ce qui devrait également rendre votre terminal réutilisable.
Voir ici pour des explications. Et d'une manière ou d'une autre, cela peut être considéré comme une mauvaise conduite de Vim , au moins Neovim n'a pas ce problème pour le moment.
la source
reset
devrais aussi.La raison est que les
xargs
ensemblesstdin
à/dev/null
, alors que lesvim
besoinsstdin
d'être/dev/tty
.xargs
Solution BSD (par exemple Mac):-o
définit lestdin
processus enfant de xarg (vim
dans ce cas) surdev/tty
.xargs
Solution GNU (par exemple Linux):GNU
xargs
n'a pas l'-o
option. Au lieu de cela, vous devrez utiliser une solution de contournement plus compliquée. (Remarque: il est très important d'avoir lazero
chaîne de fin , ne l'oubliez pas.)Vous pouvez également en faire un alias:
Explication détaillée de la solution GNU xargs
Décomposons-le étape par étape:
1.
xargs
ajoute simplement lestdin
à la fin de la chaîne, doncxargs
exécutera ceci:2. Le format de
bash -c
estbash -c 'COMMAND_STRING' $0 $1 $2 etc
."$@"
s'étend aux paramètres positionnels"$1", "$2"
, etc. Il n'inclut pas "$ 0" car il s'agit d'un paramètre spécial pour le nom du script, pas d'un paramètre positionnel. C'est pourquoi nous devons ajouter la chaîne facticezero
(il peut s'agir de n'importe quelle chaîne) pour prendre la place$0
. Sinon, vous perdrez le premier fichier.Donc, après avoir développé
"$@"
, vous vous retrouvez avec:3.
bash -c
exécutera la COMMAND_STRING:</dev/tty
définit lastdin
à/dev/tty
sorte quevim
peut travailler en mode interactif.la source
$0
espace réservé (ici "zéro") est la clé.J'ai trouvé que toutes ces réponses manquaient. Après avoir traversé le problème des xargs, la façon la plus simple - pour moi! - de faire ces recherches et ouvertures sur une boîte générique est la suivante:
Je n'ai aucun problème à utiliser
find
avecxargs
etgrep
, mais je trouve la syntaxe ennuyeuse. Et en tant que codeur quotidien qui utilisevim
le terminal comme IDE et recherche constamment des propriétés dans les fichiers, c'est ce que j'utilise.Il y a un temps et un lieu pour
find . -path ./node_modules -prune -o -name '*.js' | xargs grep -i mySearchTerm
coupler l'ouverture de fichiers via vim et d'autres méthodes. Pour moi, c'est rarement.J'espère que cela aide quelqu'un.
la source
$(...)
place. Ce n'est pas aussi important dans votre ligne de commande que dans un script mais je pense qu'il vaut toujours mieux l'utiliser dans vos réponses :) (références ici et ici )