111 votes

Comment exécuter la sortie d'une commande dans l'interpréteur de commandes actuel ?

Je suis bien conscient de la source (alias . ), qui prend le contenu d'un fichier et l'exécute dans l'interpréteur de commandes actuel.

Maintenant, je transforme du texte en commandes shell, puis je les exécute, comme suit :

$ ls | sed ... | sh

ls n'est qu'un exemple aléatoire, le texte original peut être n'importe quoi. sed également, juste un exemple de transformation de texte. La partie intéressante est sh . Je pipe tout ce que j'ai à sh et il l'exécute.

Le problème, c'est que cela signifie qu'il faut créer un nouveau sous-ensemble. Je préférerais que les commandes soient exécutées dans mon shell actuel. Comme je pourrais le faire avec source some-file si j'avais les commandes dans un fichier texte.

Je ne veux pas créer un fichier temporaire car cela me semble sale.

Par ailleurs, j'aimerais démarrer mon sous-shell avec les mêmes caractéristiques que mon shell actuel.

mise à jour

Ok, les solutions utilisant le backtick fonctionnent certainement, mais j'ai souvent besoin de le faire pendant que je vérifie et modifie la sortie, donc je préférerais qu'il y ait un moyen d'intégrer le résultat dans quelque chose à la fin.

triste mise à jour

Ah, les /dev/stdin La chose était si belle, mais, dans un cas plus complexe, elle n'a pas fonctionné.

J'ai donc ceci :

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/git mv -f $1 $2.doc/i' | source /dev/stdin

Ce qui garantit que tous les .doc ont leur extension en minuscules.

Et qui, soit dit en passant, peut être traité avec xargs mais ce n'est pas la question.

find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/$1 $2.doc/i' | xargs -L1 git mv

Ainsi, lorsque j'exécute le premier, il se termine immédiatement, rien ne se passe.

158voto

Juliano Points 13802

En eval existe précisément dans ce but.

eval "$( ls | sed... )"

Plus d'informations sur le manuel bash :

eval

          eval [arguments]

Les arguments sont concaténés ensemble en une seule commande, qui est alors lue et exécutée, et son état de sortie et son état de sortie est renvoyé en tant qu'état de sortie d'eval. de eval. S'il n'y a pas d'arguments ou des arguments vides, l'état de retour de est égal à zéro.

102voto

mark4o Points 20472
$ ls | sed ... | source /dev/stdin

UPDATE : Cela fonctionne avec bash 4.0, ainsi qu'avec tcsh et dash (si vous modifiez source a . ). Apparemment, cela était bogué dans bash 3.2. D'après le Notes de version de bash 4.0 :

Correction d'un bogue qui empêchait `.' de lire et d'exécuter des commandes provenant de fichiers non réguliers tels que des périphériques ou des tuyaux nommés.

47voto

rishta Points 198

Essayez d'utiliser substitution de processus qui remplace la sortie d'une commande par un fichier temporaire qui peut ensuite être extrait :

source <(echo id)

43voto

cluracan Points 1812

Wow, je sais que c'est une vieille question, mais je me suis retrouvé avec exactement le même problème récemment (c'est comme ça que je suis arrivé ici).

Quoi qu'il en soit, je n'aime pas les source /dev/stdin mais je pense en avoir trouvé une meilleure. En fait, elle est étonnamment simple :

echo ls -la | xargs xargs

C'est bien, non ? En fait, cela ne fait toujours pas ce que vous voulez, parce que si vous avez plusieurs lignes, il les concaténera en une seule commande au lieu d'exécuter chaque commande séparément. La solution que j'ai trouvée est donc la suivante :

ls | ... | xargs -L 1 xargs

el -L 1 signifie que vous utilisez (au maximum) une ligne par exécution de commande. Remarque : si votre ligne se termine par un espace, elle sera concaténée avec la ligne suivante ! Veillez donc à ce que chaque ligne se termine par un espace.

Enfin, vous pouvez faire

ls | ... | xargs -L 1 xargs -t

pour voir quelles commandes sont exécutées (-t est verbeux).

J'espère que quelqu'un lira ceci !

7voto

chaos Points 69029
`ls | sed ...`

Je me sens un peu comme ls | sed ... | source - serait plus jolie, mais malheureusement source ne comprend pas - pour signifier stdin .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X