В этом ответе я предполагаю систему, где /proc/$pid/environ
возвращает окружение процесса с указанным PID, с нулевыми байтами между определениями переменных. (То есть Linux, Cygwin или Solaris (?)).
export "${(@ps:\000:)$(
(Довольно прост в zsh: перенаправление ввода без команды cat FILE
. Вывод подстановки команды подвергается расширению параметров с помощью флагов ps:\000:
, означающих "разделять по нулевым байтам", и @
, означающего "если все заключено в двойные кавычки, то рассматривать каждый элемент массива как отдельное поле" (обобщение "$@"
). )
while IFS= read -r -d "" PWD; do export "$PWD"; done
(В этих оболочках пустой разделитель, переданный в read
, приводит к тому, что разделителями становятся нулевые байты. Я использую PWD
в качестве имени временной переменной, чтобы избежать нагромождения другой переменной, которая в итоге может быть импортирована. Хотя технически вы можете импортировать и PWD
, она останется на месте только до следующего cd
.)
Переносимость POSIX не так интересна для этого вопроса, потому что она применима только к системам, имеющим /proc/PID/environ
. Поэтому вопрос в том, что поддерживает Solaris sed - или есть ли в Solaris /proc/PID/environ
, раньше не было, но я сильно отстал от жизни в отношении возможностей Solaris, так что теперь может быть. В Linux утилиты GNU и BusyBox являются null-safe, но с оговорками.
Если мы настаиваем на переносимости POSIX, ни одна из текстовых утилит POSIX не обязана обрабатывать нулевые байты, так что это сложно. Вот решение, которое предполагает, что awk поддерживает нулевой байт в качестве разделителя записей (nawk и gawk поддерживают, как и BusyBox awk, но mawk не поддерживает).
eval $(
BusyBox awk (эта версия обычно встречается во встроенных Linux системах) поддерживает нулевой байт, но не устанавливает RS
в "\0"
в блоке BEGIN
и не синтаксис командной строки выше; однако он поддерживает -v 'RS="\0"'
. Я не выяснял причину, это похоже на ошибку в моей версии (Debian wheezy).
(Обернуть все строки записей, разделенных нулями, в одинарные кавычки "\047"
, после экранирования одинарных кавычек внутри значений)
Остерегайтесь, что любой из них может попытаться установить переменные только для чтения (если ваш shell имеет переменные только для чтения).
Да, есть буферный кеш чтения блочного устройства - bcache - который кэширует ранее прочитанные блоки.
Если вы не хотите этого поведения, вы можете открыть блочное устройство с флагом O_DIRECT.