Этот другой ответ хорош, он должен быть вашим первым выбором, особенно если ваш 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".
«Я не хочу, чтобы какие-либо переменные, заданные в сценарии B, могли перезаписывать что-либо в сценарии A, кроме того, что я специально пытаюсь записать» - переменные, заданные в сценарии B (в подоболочке), не будут перезаписывать никакие переменные в A. процессы не могут записывать в переменные окружения своего родительского процесса. Вам нужно будет специально захватить их.