Вещь, ядро не заботится об одном бите, как приложения интерпретируют данные, которые это дано как имя файла.
Давайте предположим, что у меня есть приложение C, которое имеет дело с исключительно строками UTF-16. И я вхожу, через правильно настроенный метод ввода, ∯ символ (Unicode 0x222F) в подсказку/диалоговое окно "Сохранить Как".
Если приложение не делает никакой формы перевода и отправляет это в простой струне до (char*
) к, скажем, fopen
в режиме записи ядро не будет видеть ∯ или даже пытаться вообразить это. Это будет видеть два char
s, один за другим, со значениями 0x22 0x2F
(принятие символов на 8 битов и никакого funnies в библиотеке C).
Таким образом, с точки зрения ядра, допустимый символ ("
) сопровождаемый /
(ASCII 0x2F). fopen
возвратится EISDIR
(т.е., "который похож на каталог и Вы запросили режим записи!").
Если я ввел ∮ (Unicode 0x222E
), ядро видело бы два прекрасных символа и создало бы файл, который, как замечено через говорящее ASCII приложение, назовут ".
.
Если я вошел a
в приложении, поскольку имя файла и приложение провели его в UTF-16 к ядру, ядро будет читать 0x00 0x61
, и на самом деле даже не рассмотрите это 0x61
, потому что 0x00
уже завершает строку, что касается его. Сообщение об ошибке совпало бы с для пустого имени файла (ENOENT
Я верю).
Таким образом, ядро действительно берет данные в качестве блоба. Это - поток char
s. Недопустимые "символы" в Вашем пространстве пользователя, кодирующем по Вашему выбору, являются теми, которые генерируют 0x00
или 0x2F
("пустой указатель" и /
) в их блобе (двоичное представление, которое передается ядру).
source tmp.txt
export a b c
./child ...
Судя Вашим другим вопросом, Вы не хотите к hardcode имена переменной:
source tmp.txt
export $(cut -d= -f1 tmp.txt)
протестируйте его:
$ source tmp.txt
$ echo "$a $b $c"
123 hello world one more variable
$ perl -E 'say "@ENV{qw(a b c)}"'
$ export $(cut -d= -f1 tmp.txt)
$ perl -E 'say "@ENV{qw(a b c)}"'
123 hello world one more variable
set -a
. ./tmp.txt
set +a
set -a
переменные причин ¹ определенный с этого времени, чтобы быть автоматически экспортированным. Это доступно в любой подобной Границе оболочке. .
стандарт и имя Bourne source
управляйте, таким образом, я предпочитаю его для мобильности (source
прибывает из csh
и теперь доступно в самых современных подобных Границе оболочках включая bash
хотя (иногда с немного отличающимся поведением)).
В оболочках POSIX можно также использовать set -o allexport
как более описательный альтернативный способ записать это (set +o allexport
сбрасывать).
¹ В bash
, остерегайтесь этого, это также вызывает все функции, объявил в то время как allexport
идет, чтобы быть экспортированным в среду (как BASH_FUNC_myfunction%%
переменные среды, которые затем импортируются всеми bash
оболочки выполняются в той среде, работая как sh
).
Просто сделай:
while read LINE; do export "$LINE"; done <./tmp.txt
опасный один -лайнер, не требующий источника:
export $(xargs <file)
Это немного опасно, потому что строки проходят через расширение bash, но мне это было полезно, когда я знал, что у меня есть безопасные файлы окружения.
небольшой обходной путь, основанный на одном из ответов:
~/.bashrc
function myenvs() {
if [ -z "$1" ]; then
echo "Usage: myenvs [import file path]";
else
if [ -f "$1" ]; then
source "$1" 2>/dev/null; export $(cat "$1" | grep "=" | grep -v "^#" | awk /./ | cut -d= -f1 | xargs)
else
echo "Bad file path: $1"
fi
fi
}
$ myenvs /path/to/env/file
для импорта envs ※ если env/file
имеет плохие линии, здесь могут появиться ошибки при вызове source
. Я просто скрываю это, поэтому обработка ошибок ложится на вас
Это решение экспортирует все key=values
в переменные среды, которые находятся в файле .env
, которые не являются пустыми строками или комментариями(#
).
Файл:.env
ENV=local
DEBUG=True
Команда:
$ export $(cat.env | egrep -v "(^#.*|^$)" | xargs)
Если вам нужно (базовое )решение, применяющее экспорт к каждой строке (ни eval
, ни source
), используйте этот скрипт:
#!/bin/bash -
exec 5<abc.env
while read -r -u 5 line ; do
line=${line%% \#*} # remove line comments.
line="${line%"${line##*[![:space:]]}"}" # remove trailing space characters.
[[ $line == "" ]] && continue # avoid empty lines.
export "$line";
done
exec 5>&-
echo "A=<$A> " "B=<$B> " "C=<$C> " "D=<$D>"
Предполагая, что abc.env
файл содержит:
$ cat./abc.env
A=1
B=2
C="3 4 5"
D="7 8" # comment added
# empty line
приведенный выше скрипт напечатает:
A=<1> B=<2> C=<"3 4 5"> D=<"7 8">
Exec должен иметь цикл без подоболочки. while... do... done <file
поместит цикл while внутри подоболочки (никакая команда export
не будет работать ).