Исходный файл / bin / sh из stdin (из другой программы) не файл


14

Вроде сложно назвать это ...

В основном у меня есть программа, которая при запуске печатает на STDOUT набор переменных оболочки:

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

Я хочу запустить это из сценария оболочки, как если бы STDOUT оценивался с source.

Я хотел бы сделать что-то вроде ...

source `./settings`

... но, конечно, это не работает.

Я знаю, что мог сделать:

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

но я действительно не хочу этого делать.

Есть какие-нибудь подсказки?

Ответы:


16

Вы можете использовать eval:

eval "$(./settings)"

eval "`./settings`"

Извините, должен был упомянуть, это / bin / sh, а не bash. $ () не работает. Я обновил вопрос.
Majenko

@Matt: Ну, sh - это удар по большинству систем. Если, конечно, вы имели в виду последние версии Ubuntu, где она была заменена на черту.
Hello71

@Matt: в этом случае, обратные галочки должны работать. Но вы должны добавить и точную версию sh- это может быть символическая ссылка на dash, ash, busybox ... Я не видел копию "настоящего 'sh'" вживую.
user1686

1
@Matt: Итак, у вас там ... интересная система. Тем более что почти все вариации "sh" поддерживают $( )- начиная с оболочки Almquist в 4.3BSD - и это тоже POSIX. (Примечание: не спорю, просто любопытно.)
user1686

$ () существует, он просто не работает в этом случае. FreeBSD 8.2's / bin / sh
Majenko

15

В системах, где /dev/fdдоступно, bash поддерживает подстановку процессов:

source <(./settings)

Здесь <( )расширится до автоматически назначенного пути, по /dev/fd/...которому ./settingsможно прочитать выходные данные .


1
В руководстве по bash это называется «замена процесса».
Гленн Джекман

6
declare `./settings`

Или конечно ...

export `./settings`

Проверьте это конечно ...

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

Обработка пробелов:

eval export `./settings`

Ага, exportтрюк работает! Спасибо
Majenko

Теперь - как я могу обрабатывать пробелы в значении?
Majenko

@Matt: я не могу использовать обратные пометки в комментариях, поэтому, пожалуйста, смотрите отредактированный ответ.
user1686

@ Grawity: Да, вы можете ...a backtick --> ` <-- and here's another one --> ` <--
Hello71

2

source /dev/stdin < ./settings

Я думаю, что / dev / stdin - это единственная вещь для Linux.


который пытается найти источник настроек. Даже с «./settings» это не с «./settings»: неоднозначный ('= backtick)
Majenko

/dev/stdinработает на BSD и Cygwin тоже.
user1686

1
Использование |, однако, не будет работать (по крайней мере, не совсем), потому что обе стороны канала являются отдельными подпроцессами, поэтому полученные команды не будут влиять на текущую оболочку.
user1686

1
отредактировано, чтобы отразить это.
LawrenceC

1
Мне нравится этот /dev/stdinтрюк, но то, что делает ваш ответ, на самом деле эквивалентно простому, source ./settingsне выполняя его. Можно было бы использовать документ-здесь , чтобы преодолеть это: source /dev/stdin <<EOF \n $(./settings) \n EOF.
tlwhitec

0

Хотелось представить другую перспективу здесь, так как другие ответы создают файлы и не извлекают напрямую из stdin. У меня есть несколько сборок, которые должны отправить подготовленную информацию о среде в несколько сценариев. То, что я делаю, готовит кучу Bash-совместимых переменных в строке:

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

Когда я готовлюсь выполнить сценарий, я base64 кодирую приведенную выше многострочную строку и передаю ее в свой сценарий оболочки:

echo base64EncodedParameters | build.sh

В build.sh я читаю из stdin, base64 декодирую и оцениваю результат.

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

echo "Hello ${Var1} ${Var2}"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.