Запишите эту конкретную переменную в стандартный вывод, затем в A:
specificvariable=$(/path/to/B.sh)
Я пытаюсь найти способ запустить сценарий оболочки B из сценария A, установить или экспортировать переменную в сценарии B и сохранить это значение в сценарии A после того, как сценарий B завершится и его суб-оболочка вернется.
Я не пытаюсь использовать сценарий B. Я хочу только одну конкретную переменную. Я могу добавить что-то в сценарий A, но я не хочу, чтобы какие-либо переменные, заданные в сценарии B, могли перезаписывать что-либо в сценарии A, кроме того, что я специально пытаюсь записать.
Я уверен, что есть несколько уродливых способов, например, записать все переменные, которые мне нужны в A, в файл, исходный скрипт B, затем прочитать все обратно из файла и восстановить переменные в A, кроме набора переменных в B что я хочу. Я ищу относительно чистый и простой способ, если таковой существует.
Запишите эту конкретную переменную в стандартный вывод, затем в A:
specificvariable=$(/path/to/B.sh)
Этот другой ответ хорош, он должен быть вашим первым выбором, особенно если ваш 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"
.