/ bin / sh Quelle von stdin (von einem anderen Programm) nicht Datei

14

Irgendwie schwierig, das zu nennen ...

Grundsätzlich habe ich ein Programm, das beim Ausführen auf STDOUT eine Reihe von Shell-Variablen druckt:

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

Ich möchte dies in einem Shell-Skript ausführen, als ob das STDOUT mit ausgewertet würde source.

Ich würde gerne so etwas machen wie ...

source `./settings`

... aber das funktioniert natürlich nicht.

Ich weiß, ich könnte tun:

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

aber das will ich wirklich nicht.

Irgendwelche Hinweise?

Majenko
quelle

Antworten:

16

Sie können verwenden eval:

eval "$(./settings)"

eval "`./settings`"
Keith
quelle
Sorry, hätte erwähnen sollen, es ist / bin / sh nicht bash. $ () funktioniert nicht. Ich habe die Frage aktualisiert.
Majenko
@ Matt: Nun, sh ist auf den meisten Systemen ein Schlag. Es sei denn, Sie meinten natürlich aktuelle Ubuntu-Versionen, bei denen es durch Bindestrich ersetzt wurde.
Hallo71
@Matt: In diesem Fall sollten Backticks funktionieren. Aber Sie sollten auch die genaue Version von hinzufügen sh- es könnte ein Symlink zu Dash, Ash, Busybox sein ... Ich habe keine Kopie von "the real 'sh'" live gesehen.
user1686
1
@Matt: Du hast also ein ... interessantes System da. Zumal fast alle "sh" -Varianten unterstützt werden $( )- beginnend mit Almquists Shell in 4.3BSD - und es ist auch POSIX. (Anmerkung: nicht streiten, nur neugierig.)
user1686
$ () existiert, es funktioniert unter diesen Umständen einfach nicht so. FreeBSD 8.2's / bin / sh
Majenko
15

Auf Systemen, auf denen /dev/fdverfügbar ist, unterstützt bash die Prozessersetzung:

source <(./settings)

Hier <( )wird auf einen automatisch zugewiesenen Pfad erweitert, unter /dev/fd/...dem die Ausgabe von ./settingsgelesen werden kann.

user1686
quelle
1
Im Bash-Handbuch wird dies als "Prozessersetzung" bezeichnet.
Glenn Jackman
6
declare `./settings`

Oder natürlich ...

export `./settings`

Teste es natürlich ...

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

Umgang mit Leerzeichen:

eval export `./settings`
Hallo71
quelle
Aha, der exportTrick funktioniert! Danke
Majenko
Nun - wie kann ich mit Leerzeichen in einem Wert umgehen?
Majenko
@Matt: Ich kann keine Backticks in Kommentaren verwenden, siehe bitte bearbeitete Antwort.
user1686
@grawity: Ja, Sie können ...a backtick --> ` <-- and here's another one --> ` <--
Hallo71
2

source /dev/stdin < ./settings

Ich denke, / dev / stdin ist eine einzige Linux-Sache.

LawrenceC
quelle
das versucht, den Inhalt der Einstellungen zu beschaffen. Sogar mit './settings' schlägt es mit './settings' fehl: Ambiguous ('= backtick)
Majenko
/dev/stdinfunktioniert auch bei BSD und Cygwin.
user1686
1
Die Verwendung |wird jedoch nicht funktionieren (zumindest nicht genau), da beide Seiten der Pipe separate Unterprozesse sind, sodass Sourcing-Befehle die aktuelle Shell nicht beeinflussen würden.
user1686
1
bearbeitet, um das zu reflektieren.
LawrenceC
1
Ich mag diesen /dev/stdinTrick, aber was Ihre Antwort tut, ist in der Tat gleichbedeutend mit einer Ebene, source ./settingsohne sie auszuführen. Man könnte ein Here-Dokument verwenden, um dies zu überwinden : source /dev/stdin <<EOF \n $(./settings) \n EOF.
Tlwhitec
0

Wollte hier eine andere Perspektive bieten, da die anderen Antworten Dateien erstellen und nicht direkt von stdin ziehen. Ich habe einige Builds, die einige vorbereitete Umgebungsinformationen an mehrere Skripte senden müssen. Ich bereite eine Reihe von Bash-kompatiblen Variablenzuweisungen in einer Zeichenfolge vor:

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

Wenn ich mich auf die Ausführung des Skripts vorbereite, codiere base64 die obige mehrzeilige Zeichenfolge und leite sie in mein Shell-Skript ein:

echo base64EncodedParameters | build.sh

In build.sh habe ich aus stdin gelesen, base64 dekodiert und das Ergebnis ausgewertet.

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

echo "Hello ${Var1} ${Var2}"
Jay Proulx
quelle