/ bin / sh źródło ze stdin (z innego programu) nie plik

11

Trudno nazwać to ...

Zasadniczo mam program, który po uruchomieniu wypisuje na STDOUT zestaw zmiennych powłoki:

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

Chcę uruchomić to w skrypcie powłoki tak, jakby STDOUT był oceniany source.

Chciałbym zrobić coś takiego ...

source `./settings`

... ale oczywiście to nie działa.

Wiem, że mógłbym:

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

ale naprawdę nie chcę tego robić.

Jakieś wskazówki?

Majenko
źródło

Odpowiedzi:

11

Możesz użyć eval:

eval "$(./settings)"

eval "`./settings`"
Keith
źródło
Przepraszam, powinienem wspomnieć, że / bin / sh nie bash. $ () nie działa. Zaktualizowałem pytanie.
Majenko
@ Mat: Cóż, sh jest bash na większości systemów. O ile oczywiście nie miałeś na myśli ostatnich wersji Ubuntu, gdzie został zastąpiony myślnikiem.
Hello71
@Matt: W takim przypadku backticks powinien działać. Ale powinieneś dodać dokładną wersję sh też - może to być dowiązanie symboliczne do myślnika, popiołu, busybox ... Nie widziałem kopii „prawdziwego„ sh ”na żywo.
grawity
1
@ Mat: Masz tam ... interesujący system. Zwłaszcza, że ​​prawie wszystkie warianty „sh” obsługują $( ) - zaczynając od powłoki Almquista 4.3BSD - i to także POSIX. (Uwaga: nie kłócąc się, tylko ciekawy.)
grawity
$ () istnieje, po prostu nie działa w ten sposób. FreeBSD 8.2 / bin / sh
Majenko
13

W systemach gdzie /dev/fd jest dostępny, bash obsługuje podstawianie procesów:

source <(./settings)

Tutaj, <( ) rozwinie się do automatycznie przypisanej ścieżki pod /dev/fd/... z którego wyjście ./settings można przeczytać.

grawity
źródło
1
W podręczniku basha nazywa się to „zastępowaniem procesu”.
glenn jackman
5
declare `./settings`

Albo oczywiście ...

export `./settings`

Przetestuj to oczywiście ...

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

Obsługa białych znaków:

eval export `./settings`
Hello71
źródło
Aha, ta export sztuczka działa! Dzięki
Majenko
Teraz - jak mogę obsługiwać spacje w wartości?
Majenko
@Matt: Nie mogę używać komentarzy w komentarzach, więc proszę zobaczyć edytowaną odpowiedź.
grawity
@ grawity: Tak, możesz ... a backtick --> ` <-- and here's another one --> ` <--
Hello71
0

source /dev/stdin < ./settings

Myślę, że / dev / stdin to jednak tylko Linux.

LawrenceC
źródło
który próbuje pobrać treść ustawień. Nawet z „./settings” kończy się niepowodzeniem z „./settings”: niejednoznaczny („= backtick)
Majenko
/dev/stdin działa również na BSD i Cygwin.
grawity
1
Za pomocą |jednak jest nie będzie działać (przynajmniej nie dokładnie), ponieważ obie strony potoku są oddzielnymi podprocesami, więc źródła poleceń nie będą miały wpływu na bieżącą powłokę.
grawity
edytowane, aby to odzwierciedlić.
LawrenceC