1

Я пытаюсь найти способ запустить сценарий оболочки B из сценария A, установить или экспортировать переменную в сценарии B и сохранить это значение в сценарии A после того, как сценарий B завершится и его суб-оболочка вернется.

Я не пытаюсь использовать сценарий B. Я хочу только одну конкретную переменную. Я могу добавить что-то в скрипт A, но я не хочу, чтобы какие-либо переменные, заданные в скрипте B, могли перезаписывать что-либо в скрипте A, кроме того, что я специально пытаюсь записать.

Я уверен, что есть несколько уродливых способов, например, записать все переменные, которые мне нужны в A, в файл, исходный скрипт B, затем прочитать все обратно из файла и восстановить переменные в A, кроме набора переменных в B что я хочу. Я ищу относительно чистый и простой способ, если таковой существует.

2 ответа2

5

Запишите эту конкретную переменную в стандартный вывод, затем в A:

specificvariable=$(/path/to/B.sh)
3

Этот другой ответ хорош, он должен быть вашим первым выбором, особенно если ваш B-скрипт делает одно и делает это хорошо (см. Философию Unix), и эта "одна вещь" означает "вычисление этого конкретного значения переменной".

Но что, если основная цель B - напечатать что-то еще? или вообще взаимодействовать с пользователем? Передача дополнительных данных через стандартный вывод требует дополнительного анализа полученного результата. Если это так, то совершенно независимый канал связи между B и A крайне желателен. В вашем случае достаточно односторонней связи.

Временный файл на самом деле очень хорош для этого. Но когда вы говорите

уродливые способы, такие как запись всех переменных, которые мне нужны в A, в файл, исходный сценарий B, затем чтение всех данных из файла и восстановление переменных в A, кроме набора переменных в B, который я хочу

Вы переворачиваете ситуацию с ног на голову, и это действительно ужасно. Правильный путь - использовать файл для передачи только этой желаемой переменной.

В:

tmpf_foo=$(mktemp)

Затем вы вызываете B с "$tmpf_foo" в качестве аргумента командной строки и обращаетесь к файлу с помощью "$1" в B (или другим числом, в зависимости от дизайна). Это может быть не удобно, если B уже анализирует свои аргументы командной строки.

Альтернативный способ - export tmpf_foo в A и ссылаться на файл как "$tmpf_foo" в B.

Если B - инструмент общего назначения, который можно использовать не только изнутри A, хорошо проверить (в B), существует ли файл, прежде чем писать в него (например, if [ -f "$tmpf_foo" ]; then …) ,

В любом случае, в B вы записываете желаемое значение в файл. Например, содержимое файла будет:

12345

После успешного завершения B, в A вы получаете значение следующим образом:

specificvariable=$(<"$tmpf_foo")

(эквивалентно specificvariable=$(cat "$tmpf_foo") но без cat ; хотя и не переносимый).

Если вам нужно передать более одной переменной из B в A, вы можете использовать несколько строк и читать их (в A) с помощью read . Но если вы заранее не знаете, какую переменную (и) следует изменить (или вообще не нужно изменять), то заставьте B создавать строки в файле, чтобы он выглядел так:

specificvariable=12345
othervariable="xyz 0"
bar=baz
unset var1

После успешного завершения B в A вы получаете файл:

. "$tmpf_foo"

Обратите внимание, что вы можете передать любую команду таким образом (в приведенном выше примере unset - это команда), и она будет выполнена изнутри A. По этой причине вы должны быть очень осторожны при записи в файл изнутри B, и вы должны убедиться, что никакие другие (мошеннический) процесс может вставлять строки в файл.

В конце (в A) вы удалите временный файл с помощью команды rm "$tmpf_foo" .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .