source / dev / stdin ne fonctionne pas comme prévu

Commençons par des tests simples qui fonctionnent pour moi pour vérifier que source /dev/stdin peut être utilisé du tout.

 # echo -ne 'echo a\necho b\n' | source /dev/stdin a b 

Maintenant, je voudrais find une fonction réelle.

 # echo -ne 'f() { echo a; }\n' | source /dev/stdin # f -bash: f: command not found 

Maintenant, essayons avec un file temporaire.

 # echo -ne 'f() { echo a; }\n' > tempf # source tempf # f a 

Ainsi, le file temporaire fonctionne. Mais c'est très incohérent dans mon cas et je ne vois aucune raison valable pour laquelle le tuyau ne devrait pas fonctionner aussi bien.

 # bash --version GNU bash, version 4.2.53(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redissortingbute it. There is NO WARRANTY, to the extent permitted by law. 

Pour être complet, le cas d'utilisation actuel consiste à sélectionner avec soin les parties d'un file qui seront incluses, afin de contourner une limitation dans Gentoo portage.

 post_src_unpack() { if type epatch_user > /dev/null 2>&1; then epatch_user || die else awk \ '/^# @FUNCTION: / { p = 0 } /^# @FUNCTION: epatch(_user)?$/ { p = 1; } p { print }' \ /usr/portage/eclass/eutils.eclass | source /dev/stdin || die epatch_user || die unset epatch unset epatch_user fi } 

Le but du code est d'extraire seulement deux fonctions epatch et epatch_user partir d'un file source avec de nombreuses fonctions, de les rendre disponibles dans le shell courant, d'en exécuter un (qui à son tour utilise l'autre) et de les supprimer. Le but final est de contourner la limitation de Gentoo que seuls les ebuilds héritant d' eutils ont access à epatch_user .

Vous pouvez utiliser la substitution de process

 source /dev/stdin < <(echo -ne 'f() { echo a; }\n') 

ou

 source <(echo -ne 'f() { echo a; }\n') 

Cela fonctionne dans bash 4.1.5, pour une raison quelconque, cela ne fonctionne pas dans 3.2.48.

Chaque partie des pipelines fonctionne dans des process séparés ou possède un sous-shell . Ainsi, lorsque vos pipelines sont terminés, votre shell actuel ne sait rien de la fonction f .

Avec bash ( ksh , pdksh , zsh , mksh ou shell supportant Here-Ssortingng ), vous pouvez utiliser:

 $ source /dev/stdin <<<'f() { echo a; }' $ f a 

POSIXly, vous devriez utiliser Here-Document et dot :

 $ . /dev/stdin <<'EOF' > f() { echo a; } > EOF $ f a 

Les commands dans un pipe sont des process séparés, d'où la définition de la fonction qui provient de /dev/stdin est perdue dès que le tube est terminé. C'est pourquoi la pipe montre différents résultats à l'utilisation du file temporaire.

Dans votre cas d'utilisation, l'évaluation proposée par PM 2Ring serait la voie à suivre.