Как экспортировать переменные из файла?

Вещь, ядро не заботится об одном бите, как приложения интерпретируют данные, которые это дано как имя файла.

Давайте предположим, что у меня есть приложение C, которое имеет дело с исключительно строками UTF-16. И я вхожу, через правильно настроенный метод ввода, ∯ символ (Unicode 0x222F) в подсказку/диалоговое окно "Сохранить Как".

Если приложение не делает никакой формы перевода и отправляет это в простой струне до (char*) к, скажем, fopen в режиме записи ядро не будет видеть ∯ или даже пытаться вообразить это. Это будет видеть два chars, один за другим, со значениями 0x22 0x2F (принятие символов на 8 битов и никакого funnies в библиотеке C).
Таким образом, с точки зрения ядра, допустимый символ (") сопровождаемый / (ASCII 0x2F). fopen возвратится EISDIR (т.е., "который похож на каталог и Вы запросили режим записи!").
Если я ввел ∮ (Unicode 0x222E), ядро видело бы два прекрасных символа и создало бы файл, который, как замечено через говорящее ASCII приложение, назовут "..

Если я вошел a в приложении, поскольку имя файла и приложение провели его в UTF-16 к ядру, ядро будет читать 0x00 0x61, и на самом деле даже не рассмотрите это 0x61, потому что 0x00 уже завершает строку, что касается его. Сообщение об ошибке совпало бы с для пустого имени файла (ENOENT Я верю).

Таким образом, ядро действительно берет данные в качестве блоба. Это - поток chars. Недопустимые "символы" в Вашем пространстве пользователя, кодирующем по Вашему выбору, являются теми, которые генерируют 0x00 или 0x2F ("пустой указатель" и /) в их блобе (двоичное представление, которое передается ядру).

86
20.03.2018, 10:48
7 ответов
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
71
27.01.2020, 19:30
  • 1
    Это не будет работать, если файл среды будет содержать комментарии, например. (например, файлы, которые могут быть снова использованы EnvironmentFile systemd), –  Chris Lamb 13.11.2017, 00:36
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).

192
27.01.2020, 19:30

Просто сделай:

while read LINE; do export "$LINE"; done <./tmp.txt
3
27.01.2020, 19:30

опасный один -лайнер, не требующий источника:

export $(xargs <file)
  • Он не может обрабатывать комментарии, часто используемые в файлах окружения
  • Он не может обрабатывать значения с пробелами, как в примере вопроса
  • Шаблоны глобусов могут быть непреднамеренно расширены в файлы, если они случайно совпадают

Это немного опасно, потому что строки проходят через расширение bash, но мне это было полезно, когда я знал, что у меня есть безопасные файлы окружения.

9
27.01.2020, 19:30

небольшой обходной путь, основанный на одном из ответов:

  1. создайте функцию и поместите ее в~/.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
}
  1. запустите $ myenvs /path/to/env/fileдля импорта envs

※ если env/fileимеет плохие линии, здесь могут появиться ошибки при вызове source. Я просто скрываю это, поэтому обработка ошибок ложится на вас

0
22.01.2021, 08:49

Это решение экспортирует все key=valuesв переменные среды, которые находятся в файле .env, которые не являются пустыми строками или комментариями(#).

Файл:.env

ENV=local
DEBUG=True

Команда:

$ export $(cat.env | egrep -v "(^#.*|^$)" | xargs)
1
22.03.2021, 11:55

Если вам нужно (базовое )решение, применяющее экспорт к каждой строке (ни 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не будет работать ).

0
04.09.2021, 21:28

Теги

Похожие вопросы