сохраните и восстановите переменные оболочки

У меня есть два сценария оболочки, которые я хотел бы вызвать из программы C. Я хотел бы, чтобы набор переменных оболочки в первом сценарии был видим во втором. Вот то, на что это было бы похоже:

a.sh:

var=blah
<save vars>

b.sh:

<restore vars>
echo $var

Лучшим, который я придумал до сих пор, является вариант на "наборе>/tmp/vars" для сохранения переменных и "$ оценки (кошка/tmp/vars)" для восстановления их. "Оценка" дросселирует, когда она пытается восстановить переменную только для чтения, таким образом, мне нужны к grep они. Список этих переменных доступен через, "объявляют-r". Но существует некоторый Вар, которые не обнаруживаются в этом списке, и все же не может быть установлен в оценке, например, BASH_ARGC. Таким образом, мне нужны к grep они, также.

На данном этапе мое решение чувствует себя очень хрупким и подверженным ошибкам, и я не уверен, насколько портативный это. Существует ли лучший способ сделать это?

6
задан eruciform 11 July 2010 в 20:03
поделиться

4 ответа

Один из способов избежать установки проблемных переменных - сохранить только те, которые были изменены во время выполнения каждого скрипта. Например,

a.sh:

set > /tmp/pre
foo=bar
set > /tmp/post
grep -v -F -f/tmp/pre /tmp/post > /tmp/vars

b.sh:

eval $(cat /tmp/vars)
echo $foo

/ tmp / vars содержит следующее:

PIPESTATUS=([0]="0")
_=
foo=bar

Очевидно, исключение первых двух строк не имеет отрицательного эффекта.

5
ответ дан 17 December 2019 в 00:02
поделиться

Если вы можете использовать общий префикс в именах переменных, вот один из способов сделать это:

# save the variables
yourprefix_width=1200
yourprefix_height=2150
yourprefix_length=1975
yourprefix_material=gravel
yourprefix_customer_array=("Acme Plumbing" "123 Main" "Anytown")
declare -p $(echo ${!yourprefix@}) > varfile

# load the variables
while read -r line
do
    if [[ $line == declare\ * ]]
    then
        eval "$line"
    fi
done < varfile

Конечно, ваш префикс будет короче. Вы можете выполнить дополнительную проверку при загрузке переменных, чтобы убедиться, что имена переменных соответствуют вашей схеме именования.

Преимущество использования declare состоит в том, что это более безопасно, чем просто использование eval отдельно.

При необходимости вы можете отфильтровать переменные, помеченные как доступные только для чтения, или выбрать переменные, помеченные для экспорта.

Другие интересующие команды (некоторые могут отличаться в зависимости от версии Bash):

  • export - без аргументов перечисляет все экспортируемые переменные в формате declare
  • declare -px - то же, что и предыдущая команда
  • declare -pr - перечисляет переменные только для чтения
2
ответ дан 17 December 2019 в 00:02
поделиться

Если a.sh может вызывать b.sh, он будет перенесен, если они будут экспортированы. Или родитель устанавливает все необходимые значения, а затем вызывает оба. Это самый безопасный и надежный метод, о котором я могу думать.

Не уверен, принята ли это догма, но:

bash -c 'export foo=bar; env > xxxx'
env `cat xxxx` otherscript.sh

В другом сценарии env будет напечатано как xxxx ...

Обновление:

Также примечание:

man execle

О том, как установить переменные среды для другой системы звоните изнутри C, если вам это нужно. И:

man getenv

и http://www.crasseux.com/books/ctutorial/Environment-variables.html

0
ответ дан 17 December 2019 в 00:02
поделиться

Альтернативой сохранению и восстановлению состояния оболочки было бы заставить программу C и программу оболочки работать параллельно: программа C запускает программу оболочки, которая запускает a.sh , затем уведомляет C программа (возможно, передавая некоторую информацию, полученную при выполнении a.sh ), и когда программа C готова к дальнейшим действиям, она сообщает программе оболочки запустить b.sh . Программа оболочки будет выглядеть так:

. a.sh
echo "information gleaned from a"
arguments_for_b=$(read -r)
. b.sh

И общая структура программы C будет:

  • установить две пары каналов, одну для C-> shell и одну для shell-> C
  • fork, exec оболочка оболочки
  • чтение информации, полученной из a в канале оболочки-> C
  • дополнительная обработка
  • запись аргументов для b в канале оболочки C->
  • ожидание завершения дочернего процесса
0
ответ дан 17 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: