Допустимые символы в именах переменных среды Linux

Какие символы разрешены в именах переменных среды Linux? Мой беглый поиск по страницам руководства и по сети дал только информацию о том, как работать с переменными, но не о том, какие имена разрешены.

У меня есть Java-программа, которая требует определенной переменной среды, содержащей точку, как com.example.fancyproperty, В Windows я могу установить эту переменную, но мне не повезло установить ее в Linux (пробовал в SuSE и Ubuntu). Это имя переменной даже разрешено?

8 ответов

Решение

Из открытой группы:

Эти строки имеют форму имя = значение; имена не должны содержать символ '='. Для значений, переносимых между системами, соответствующими стандарту IEEE Std 1003.1-2001, значение должно состоять из символов из переносимого набора символов (кроме NUL и как указано ниже).

Таким образом, имена могут содержать любой символ, кроме = и NUL, но:

Имена переменных среды, используемые утилитами в разделе "Оболочки и утилиты" стандарта IEEE Std 1003.1-2001, состоят исключительно из заглавных букв, цифр и символа "_" (подчеркивание) из символов, определенных в переносимом наборе символов, и не начинаются с цифры, Другие символы могут быть разрешены реализацией; Заявки должны терпеть наличие таких имен.

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

Раздел стандартов POSIX для оболочек стандарта IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Shell and Tools не определяет лексическое соглашение для имен переменных, однако беглый взгляд на источник показывает, что он использует нечто подобное

[a-zA-Z_]+[a-zA-Z0-9_]*

(Редактировать: Добавлено недостающее подчеркивание во втором классе символов.)

Небольшое замечание, так как некоторые оболочки не поддерживают + в регулярном выражении, потенциально более переносимое регулярное выражение может быть:

[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}

Мое быстрое тестирование показало, что они в основном следуют тем же правилам, что и имена переменных C, а именно

  1. аз, аз, _ и 0-9
  2. НЕ может начинаться с цифры

Так что это исключает . внутри них. Любое недопустимое имя переменной указывается unknown command,

Это было проверено в ZSH, который в основном совместим с BASH.

ДА, ТЫ МОЖЕШЬ СДЕЛАТЬ ЭТО.

Использовать exec а также env команда для реализации этой сцены.

Тестовое приспособление в Docker

docker run -it --rm alpine:3.10

Запустить команду в контейнере:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}

Проверьте переменные среды:

HOSTNAME=bd0bccfdc53b
SHLVL=2
HOME=/root
spring.application_name=happy-variable-name
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

Использовать ps aux для проверки PID не изменен

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux

Использовать python чтобы проверить переменную окружения

apk add python
python -c 'import os; print(os.environ["spring.application_name"])'

ВЫХОД happy-variable-name.

Что случилось?

  1. Встроенный вызов оболочки exec
  2. Встроенный в оболочку exec вызов syscall.exec create process 'env' для замены текущей оболочки
  3. вызов процесса env syscall.execvp create process '/bin/sh' для замены процесса env

По-другому

  • Образ докера

Если вы используете докер, вы можете установить переменную в Dockerfile

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Карта конфигурации Kubernetes

Если вы используете кубернеты, вы можете установить переменную с помощью ConfigMap

test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-config
data:
  "xx.ff-bar": "1234"

---
apiVersion: v1
kind: Pod
metadata:
  name: foobar
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: foo-config
  restartPolicy: Never

Развернуть модуль kubectl apply -f test.yaml

Проверить kubectl logs foobar выход:

xx.ff-bar=1234

ConfigMap разрешает '-', '_' или '.'

Зависит от того, что вы подразумеваете под "разрешено".

Игнорирование Windows для одноразового номера:

Среда представляет собой массив строк, передаваемых основной функции программы. Если вы прочитаете execve(2), вы не увидите никаких требований или ограничений на эти строки, кроме нулевого завершения.

По соглашению каждая строка состоит из NAME=value. Соглашения о цитировании не существует, поэтому в этом соглашении не должно быть символа "=".

Нормальные люди устанавливают эти строки, обсуждая их со своей оболочкой. Каждая оболочка имеет свои собственные представления о том, что является допустимыми переменными NAMEs, поэтому вы должны прочитать справочную страницу для оболочки на момент, чтобы увидеть, что она думает.

Обычно такие вещи, как com.baseball.spit=fleagh, являются системными свойствами Java, и независимо от того, желает ли какая-либо программа Java вернуться к среде, лучше указывать их с помощью -D.

Это зависит от оболочки. Я предполагаю, что вы используете bash по умолчанию, в этом случае разрешены буквы, цифры и подчеркивания, но вы не можете начинать имя переменной с цифры. Начиная с Bash v.3, периоды не допускаются в именах переменных.

Хотя большая часть оболочки не позволяет устанавливать переменные среды (как упоминалось в других ответах), при необходимости вы можете выполнять другие программы с нестандартными переменными среды, используя env(1).

Например, удаление всего окружения и настроек Strange.Env:Var оценивать foo, и выполнение программы perl, которая его печатает:

env -i Strange.Env:Var=foo perl -MData::Dumper -E 'say Dumper(\%ENV)'

напечатает

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };

При редактировании переменных службы systemd с помощью systemctl edit <service_name>Я могу использовать все символы, кроме " = \ $как:

      [Service]
Environment="TOKEN=~'+*^,j-;H@[J;;G,g&xG:eH)RfK@I&fjjgdZ|IXKm]-[C"

И это работает без проблем.

Другие вопросы по тегам