/ bin / sh sorgente da stdin (da altro programma) non file


14

Un po 'complicato per nominare questo ...

Fondamentalmente ho un programma che quando eseguito stampa su STDOUT un insieme di variabili shell:

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

Voglio eseguirlo dall'interno di uno script di shell come se lo STDOUT fosse valutato source.

Mi piacerebbe fare qualcosa come ...

source `./settings`

... ma ovviamente non funziona.

So che potrei fare:

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

ma non voglio davvero farlo.

Qualche indizio?

Risposte:


16

Puoi usare eval:

eval "$(./settings)"

eval "`./settings`"

Scusa, avrei dovuto dirlo, è / bin / sh non bash. $ () non funziona. Ho aggiornato la domanda.
Majenko,

@Matt: Beh, sh è bash sulla maggior parte dei sistemi. A meno che, naturalmente, non intendessi le recenti versioni di Ubuntu, dove è stato sostituito con trattino.
Ciao, il

@Matt: in tal caso, i backtick dovrebbero funzionare. Ma dovresti aggiungere anche la versione esatta di sh- potrebbe essere un collegamento simbolico a dash, ash, busybox ... Non ho visto una copia del "vero" sh "dal vivo.
user1686,

1
@Matt: Quindi hai un ... sistema interessante lì. Soprattutto dal momento che quasi tutte le varianti "sh" supportano $( )- a partire dalla shell di Almquist in 4.3BSD - ed è anche POSIX. (Nota: non discutere, solo curioso.)
user1686

$ () esiste, semplicemente non funziona così in questa circostanza. FreeBSD 8.2's / bin / sh
Majenko,

15

Su sistemi dove /dev/fdè disponibile, bash supporta la sostituzione di processo:

source <(./settings)

Qui, <( )si espanderà in un percorso assegnato automaticamente in base /dev/fd/...al quale è ./settingspossibile leggere l'output di .


1
Nel manuale di bash, questo è chiamato "sostituzione di processo".
Glenn Jackman,

6
declare `./settings`

O ovviamente ...

export `./settings`

Provalo ovviamente ...

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

Gestione degli spazi bianchi:

eval export `./settings`

Ah, il exporttrucco funziona! Grazie
Majenko,

Ora: come posso gestire gli spazi in un valore?
Majenko,

@Matt: non posso usare i backtick nei commenti, quindi per favore vedi la risposta modificata.
user1686,

@grawity: Sì, puoi ...a backtick --> ` <-- and here's another one --> ` <--
Hello71,

2

source /dev/stdin < ./settings

Penso che / dev / stdin sia solo una cosa di Linux.


che tenta di procurarsi il contenuto delle impostazioni. Anche con './settings' non riesce con './settings': Ambiguous ('= backtick)
Majenko,

/dev/stdinfunziona anche su BSD e Cygwin.
user1686,

1
L'uso |, tuttavia, non funzionerà (almeno non esattamente), poiché entrambi i lati della pipe sono sottoprocessi separati, quindi i comandi provenienti non influirebbero sulla shell corrente.
user1686,

1
modificato per riflettere ciò.
LawrenceC,

1
Mi piace questo /dev/stdintrucco, ma quello che fa la tua risposta è in effetti equivalente a una semplice source ./settingssenza eseguirla. Si potrebbe utilizzare un qui-documento per superare questo: source /dev/stdin <<EOF \n $(./settings) \n EOF.
tlwhitec,

0

Volevo fornire un'altra prospettiva qui, poiché le altre risposte creano file e non traggono direttamente da stdin. Ho alcune build che devono inviare alcune informazioni sull'ambiente preparate a più script. Quello che sto facendo è preparare una serie di assegnazioni di variabili compatibili con Bash in una stringa:

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

Quando mi preparo per eseguire lo script, base64 codifico la stringa multilinea sopra e la instrada nel mio script shell:

echo base64EncodedParameters | build.sh

In build.sh ho letto da stdin, decodifica base64 ed ho valutato il risultato.

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

echo "Hello ${Var1} ${Var2}"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.