Commande de source d'alimentation avec un tuyau

25

Auparavant, j'utilisais une sourcecommande comme celle-ci:

source file_name

Mais ce que j'essaie de faire, c'est ceci:

echo something | source

Ce qui ne marche pas.

Desmond Hume
la source

Réponses:

38

Puisque source(ou .) prend un fichier en argument, vous pouvez essayer:

source <(echo something)
muru
la source
1
Cela a fonctionné, merci. Et bonne année!
Desmond Hume
@muru Cela fonctionne très bien. Notez que "| source / dev / stdin" a l' air de fonctionner, mais il supprimera en fait toutes les affectations de variables. Pas certain de pourquoi. Semble solide en théorie. C'est de la folie.
Dustin Oprea
2
Les tuyaux @DustinOprea créent un sous-shell, de sorte que toutes ces affectations de variables n'affectent jamais le shell parent.
muru
8

Votre commande source nécessite un argument de fichier. Vous pouvez l'obtenir dans certains shells avec une substitution de processus, et c'est parce que de la même manière le shell remplace ...

arg=$(echo hi)

... le echobit sur la ligne de commande avec la sortie du sous-shell, dans le cas de la substitution de processus, il remplace le sous-shell par un fichier nommé - généralement /dev/fd/62ou quelque chose - un lien vers un descripteur de fichier. Avec un pipe le descripteur de fichier est 0 donc ...

echo 'echo hi' | . /dev/fd/0

... /dev/stdinou quoi que ce soit selon le cas devrait fonctionner très bien sur n'importe quel système Linux - et bien d'autres encore. Vous pouvez également utiliser ici-documents de manière similaire:

. /dev/fd/3 3<<HI
$(echo 'echo hi')
HI

Vous pouvez vérifier la façon dont votre shell gère la substitution de processus, en passant:

(set -x; readlink <(:))

... qui imprime (en bash) :

+ set +x
+ readlink /dev/fd/63
++ :
pipe:[2212581]

... et ainsi nous pouvons voir que le shell fait la substitution et readlinklit à partir d'un tube anoyme qu'il ouvre sur le descripteur de fichier 63.

mikeserv
la source