Você pode usar a substituição de processos
source /dev/stdin < <(echo -ne 'f() { echo a; }\n')
ou
source <(echo -ne 'f() { echo a; }\n')
Isso funciona no bash 4.1.5, por alguma razão, não funciona em 3.2.48.
Vamos começar com testes simples que funcionam para eu verificar se source /dev/stdin
pode ser usado.
# echo -ne 'echo a\necho b\n' | source /dev/stdin
a
b
Agora eu gostaria de obter uma função real.
# echo -ne 'f() { echo a; }\n' | source /dev/stdin
# f
-bash: f: command not found
Agora vamos tentar com um arquivo temporário.
# echo -ne 'f() { echo a; }\n' > tempf
# source tempf
# f
a
Então o arquivo temporário funciona. Mas é muito incerto no meu caso e não vejo nenhum motivo válido pelo qual o pipe não funcione tão bem.
# 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 redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Para completar, o caso de uso real é selecionar cuidadosamente quais partes de um arquivo serão incluídas, a fim de contornar uma limitação na portabilidade do Gentoo.
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
}
A finalidade do código é extrair apenas duas funções necessárias epatch
e epatch_user
de um arquivo de origem com muitas funções, disponibilizá-las no shell atual, executar uma delas (que, por sua vez, usa as outras ) e remova-os. O objetivo final é solucionar a limitação do Gentoo de que apenas ebuilds herdando eutils
tenham acesso a epatch_user
.
Você pode usar a substituição de processos
source /dev/stdin < <(echo -ne 'f() { echo a; }\n')
ou
source <(echo -ne 'f() { echo a; }\n')
Isso funciona no bash 4.1.5, por alguma razão, não funciona em 3.2.48.
Cada parte dos pipelines é executada em processos separados ou sub-pasta própria . Então, quando seus pipelines terminarem, seu shell atual não sabe nada sobre a função f
.
Com bash
( ksh
, pdksh
, zsh
, mksh
ou shell que suporta Here-String ), você pode usar:
$ source /dev/stdin <<<'f() { echo a; }'
$ f
a
POSIXly, você deve usar aqui documento e ponto :
$ . /dev/stdin <<'EOF'
> f() { echo a; }
> EOF
$ f
a
Os comandos em um pipe são processos separados, portanto, a definição de função originada de /dev/stdin
é perdida assim que o pipe é concluído. É por isso que o pipe mostra resultados diferentes para o uso do arquivo temporário.
No seu caso de uso, o eval
sugerido por PM 2Ring seria o caminho a seguir.
Tags bash pipe shell-script