/ bin / sh fonte do stdin (de outro programa) não arquiva


14

É meio complicado nomear isso ...

Basicamente, eu tenho um programa que, quando executado, imprime no STDOUT um conjunto de variáveis ​​de shell:

$ ./settings
SETTING_ONE="this is setting one"
SETTING_TWO="This is the second setting"
ANOTHER_SETTING="This is another setting".

Eu quero executar isso de dentro de um script de shell como se o STDOUT estivesse sendo avaliado source.

Eu gostaria de fazer algo como ...

source `./settings`

... mas é claro que isso não funciona.

Eu sei que eu poderia fazer:

./settings >/tmp/file
source /tmp/file

mas eu realmente não quero fazer isso.

Alguma pista?

Respostas:


16

Você pode usar eval:

eval "$(./settings)"

eval "`./settings`"

Desculpe, deveria ter mencionado, não é / bin / sh bash. $ () não funciona. Eu atualizei a pergunta.
Majenko 18/04/11

@ Matt: Bem, sh é uma festa na maioria dos sistemas. A menos, é claro, que você quis dizer versões recentes do Ubuntu, onde foi substituído por traço.
Hello71

@ Matt: Nesse caso, os backticks devem funcionar. Mas você também deve adicionar a versão exata sh- pode ser um link simbólico para traço, cinzas, busybox ... Eu não vi uma cópia do "the real 'sh'" ao vivo.
usar o seguinte comando

1
@ Matt: Então você tem um ... sistema interessante lá. Especialmente porque quase todas as variações "sh" suportam $( )- começando pelo shell de Almquist no 4.3BSD - e também pelo POSIX. (Nota:. Não discutindo, apenas curioso)
user1686

$ () existe, simplesmente não funciona assim nessa circunstância. FreeBSD 8.2 / bin / sh
Majenko

15

Nos sistemas onde /dev/fdestá disponível, o bash suporta a substituição de processos:

source <(./settings)

Aqui, <( )será expandido para um caminho atribuído automaticamente, no /dev/fd/...qual a saída de ./settingspode ser lida.


1
No manual do bash, isso é chamado de "substituição de processo".
Glenn Jackman

6
declare `./settings`

Ou claro ...

export `./settings`

Teste, é claro ...

export `echo -e "asdf=test\nqwerty=dvorak"` ; echo $asdf $qwerty

Manipulação de espaço em branco:

eval export `./settings`

Aha, o exporttruque funciona! Obrigado
Majenko

Agora - como posso lidar com espaços em um valor?
Majenko

@ Matt: Eu não posso usar backticks nos comentários, então, por favor, veja a resposta editada.
usar o seguinte comando

@grawity: Sim, você pode ...a backtick --> ` <-- and here's another one --> ` <--
Hello71

2

source /dev/stdin < ./settings

Eu acho que / dev / stdin é apenas uma coisa do Linux.


que tenta obter o conteúdo das configurações. Mesmo com './settings', ele falha com './settings': Ambíguo ('= backtick)
Majenko 18/04/11

/dev/stdinTambém trabalha com BSD e Cygwin.
user1686

1
Usar |, no entanto, não vai funcionar (pelo menos não exatamente), porque os dois lados do canal são subprocessos separados, portanto, os comandos de origem não afetariam o shell atual.
usar o seguinte comando

1
editado para refletir isso.
LawrenceC

1
Eu gosto desse /dev/stdintruque, mas o que sua resposta faz é de fato equivalente a uma planície source ./settingssem executá-lo. Pode-se usar um here-document para superar este: source /dev/stdin <<EOF \n $(./settings) \n EOF.
tlwhitec 27/05/19

0

Queria fornecer outra perspectiva aqui, pois as outras respostas criam arquivos e não são extraídas diretamente do stdin. Eu tenho algumas compilações que precisam enviar algumas informações de ambiente preparadas para vários scripts. O que estou fazendo é preparar várias atribuições de variáveis ​​compatíveis com o Bash em uma string:

Var1="Foo"
Var2="Bar"
Var3="Baz"

Quando estou me preparando para executar o script, eu base64 codifico a sequência multilinha acima e a canalizo para o meu shell script:

echo base64EncodedParameters | build.sh

No build.sh, li no stdin, decodifique a base64 e avalie o resultado.

params=""
while read line; do params="${params}${line}"; done
eval `echo $params | base64 -D`

echo "Hello ${Var1} ${Var2}"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.