/ 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 не баш. $ () не працює. Я оновив питання.
Majenko

@Matt: Добре, що шум у більшості систем. Якщо, звичайно, ви не мали на увазі останні версії Ubuntu, де його було замінено тире.
Привіт71,

@Matt: У такому випадку задні фон повинен працювати. Але ви також повинні додати точну версію sh- це може бути символьним посиланням на тире, золу, зайняту скриньку ... Я не бачив копії "справжнього" ш "" в прямому ефірі.
користувач1686

1
@Matt: Отже, у вас є ... цікава система. Тим більше, що майже всі "ш" варіації підтримують $( )- починаючи з оболонки Almquist в 4.3BSD - і це також POSIX. (Примітка: не сперечаюся, просто цікаво.)
користувач1686

$ () існує, він просто не працює так у цій обставині. FreeBSD 8.2's / bin / sh
Majenko

15

У системах, де /dev/fdдоступні, bash підтримує процес заміни:

source <(./settings)

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


1
У посібнику з bash це називається "заміна процесу".
glenn jackman

6
declare `./settings`

Або звичайно ...

export `./settings`

Перевірте це, звичайно ...

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

Поводження з пробілом:

eval export `./settings`

Ага, exportфокус працює! Спасибі
Маєнко

Тепер - як я можу обробляти пробіли у значенні?
Маєнко

@Matt: Я не можу використовувати зворотні посилання в коментарях, тому, будь ласка, дивіться відредаговану відповідь.
користувач1686

@grawity: Так, ви можете ...a backtick --> ` <-- and here's another one --> ` <--
Hello71,

2

source /dev/stdin < ./settings

Я думаю, що / dev / stdin - це лише Linux.


що намагається створити вміст налаштувань. Навіть із './settings' він не вдається з './settings': Ambiguous ('=
backtick

/dev/stdinпрацює і на BSD, і на Cygwin.
користувач1686

1
Використовуючи |, проте, НЕ буде працювати (по крайней мере , не зовсім), так як обидві сторони труби окремі підпроцеси, тому Sourced команди не впливає на поточну оболонку.
користувач1686

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.