Дозволені символи у змінних імен середовища середовища Linux


143

Які символи дозволені в змінних імен середовища середовища Linux? Мій побіжний пошук довідкових сторінок і в Інтернеті дав лише інформацію про те, як працювати зі змінними, але не те, які імена дозволені.

У мене є програма Java, яка вимагає визначеної змінної середовища, що містить крапку, наприклад com.example.fancyproperty. У Windows я можу встановити цю змінну, але мені не пощастило встановити її в linux (спробував у SuSE та Ubuntu). Чи дозволено це ім’я змінної?


3
На щастя, я виявив, що програма настільки ж задоволена властивістю системи Java (оголошена -Dопцією командного рядка), тому вона працює і зараз. Очевидно, що програма виглядає в обох змінних наборах, не повідомляючи мені. Але все ж мені цікаво, які назви змінних середовищ дозволені.
Крістіан Семрау

@AleksandrDubinsky Я її видалив. Це схоже, але щодо визначення псевдоніму не зовсім змінні середовища stackoverflow.com/questions/24690640/…
Lime

1
Якщо ви використовуєте Spring , то за замовчуванням SystemEnvironmentPropertySource також буде шукати com_example_fancypropertyта COM_EXAMPLE_FANCYPROPERTY.
Олександр Дубінський,

Відповіді:


203

Від The Open Group :

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

Отже, імена можуть містити будь-який символ, крім = та NUL, але:

Імена змінних оточуючих середовищ, які використовуються утилітами в томі оболонки Shell and Utilities IEEE Std 1003.1-2001, складаються виключно з великих літер, цифр та символу '_' (підкреслення) з символів, визначених у наборі символів переносних, і не починаються з цифри . Інші символи можуть бути дозволені реалізацією; програми допускають наявність таких назв.

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


8
Просто перевірка: друга цитата ненормативна: вона просто зауважує, що змінні, які POSIX визначає як особливі для своїх утиліт, є [a-zA-Z_][a-zA-Z0-9_]*(явно передбачаючи, що ця форма є більш безпечною), але власне специфікація (цитата 1) вимагає всієї реалізації, щоб підтримувати що-небудь, але =і NUL?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
Крім того, "портативний набір символів" pubs.opengroup.org/onlinepubs/000095399/basedefs/… містить такі речі, як пробіли та недруковані: ми можемо використовувати ці речі чи ні?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
Це саме те, що я спостерігаю. Shell не любить спеціальні символи як частину імені змінної. Однак коли одна програма чи сценарій (наприклад, java чи perl) ініціалізує змінну зі спеціальними символами у своєму імені та викликає інший виконуваний файл (дочірній процес), останній виконуваний файл може отримати доступ до цієї змінної без проблем.
оᴉɹǝɥɔ

1
@checksum, UPPERCASE прямо вказаний для імен змінних із значенням для визначених POSIX інструментів, включаючи оболонку; імена, що мають принаймні один нижній регістр, явно зарезервовані для використання додатків. Таким чином, найкраща практика полягає в тому, щоб включити принаймні один маленький символ у назви змінних ваших додатків, щоб переконатися, що ви не будете ненавмисно перезаписувати (оскільки встановлення змінної оболонки замінить будь-яку названу змінну оточуючого середовища) змінної зі значенням система. Дивіться pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Чарльз Даффі

2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, ви можете використовувати їх у змінних середовища; ви не можете використовувати їх у змінних оболонок, і ці змінні середовища не гарантовано будуть доступними з оболонки.
Чарльз Даффі

37

Розділ стандартів POSIX для оболонок IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Стандарт оболонки та інструментів не визначає лексичну умову для імен змінних, однак короткий погляд на джерело показує, що він використовує щось подібне до

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

(Редагувати. Додано відсутність підкреслення в другому класі символів.)

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

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


4
Спасибі, Ейден Я думаю, що у другому наборі квадратних дужок відсутнє підкреслення: Мабуть, слід сказати: [a-zA-Z_][a-zA-Z0-9_]* Для таких, як я, хто вважає посилання на bash-4.1 трохи невиразним (616'000 рядків коду), ось кілька підказок на знайдіть відповідні рядки коду: subst.c: param_expand(), in the default case-> general.h:/ * Визначте, з чого саме складається юридичний ідентифікатор оболонки. * / #define legal_variable_starter (c) (ISALPHA (c) || ​​(c == ' ')) #define legal_variable_char (c) (ISALNUM (c) || ​​c == ' ')
Кріс

3
Вам не потрібен цей плюс у першому класі символів.
scravy

2
@scravy правда, хоча я взяв звідки згенером, тому я буду тримати +.
Ейден Белл

4
POSIX визначає: 3.231 Назва a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit .

Не в розділі оболонки, але абсолютно є стандарти POSIX, які включають в себе умови для іменування змінних оточуючих середовищ (і фактично обговорюють імена, зарезервовані для використання оболонки). Дивіться pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Чарльз Даффі

12

Моє швидке тестування показало, що вони в основному дотримуються тих же правил, що імена C змінних, а саме

  1. az, AZ, _ і 0-9
  2. НЕ може починатися з числа

Тож це виключає . всередині них. Будь-яке незаконне ім’я змінної зараховуєтьсяunknown command .

Це було перевірено на ZSH, який здебільшого сумісний з БАШ.


6

Залежить від того, що ви маєте на увазі під "дозволеним".

Ігнорування Windows ніколи:

Середовище - це масив рядків, переданих основній функції програми. Якщо ви прочитаєте execve (2), ви не побачите жодних вимог або обмежень для цих рядків, крім нульового припинення.

За умовою, кожен рядок складається з значення NAME = значення. Конвенція котирування не існує, тому ви не можете мати ім'я '=' у цій конвенції.

Нормальні люди встановлюють ці рядки, обговорюючи їх зі своєю оболонкою. Кожна оболонка має власні уявлення про те, що є дійсними іменними змінними, тому вам доведеться прочитати сторінку man для оболонки моменту, щоб побачити, що вона думає.

Взагалі такі речі, як com.baseball.spit = fleagh, є системними властивостями Java, і чи хотіла б якась програма Java повернутися до середовища, краще вказати їх з -D.


Я мав би раніше прийти до висновку, що змінна форматується як властивість системи Java, а не намагатися встановити її як змінну середовища.
Крістіан Семрау


4

ТАК, ВИ МОЖЕТЕ ВІН ЗРОБИТИ.

Використовуйте execта envкомандуйте для реалізації цієї сцени.

Тестовий кріплення в Докер

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для перевірки змінної environemnt

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

ВИХІД є happy-variable-name.

Що сталося?

  1. Shell call вбудований exec
  2. Shell вбудований exec викликає syscall.exec створити процес 'env' для заміни поточної оболонки
  3. env процес виклику syscall.execvp створити процес '/ bin / sh', щоб замінити env процес

Інший спосіб

  • Зображення Докера

Якщо ви використовуєте docker, ви можете встановити змінну в Dockerfile

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Налаштування Kubernetes

Якщо ви використовуєте kubernetes, ви можете встановити змінну за допомогою ConfigMap

тест.ямл

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 дозволяють '-', '_' або '.'


0

Хоча більшість оболонок не дозволять встановлювати змінні середовища (як зазначено в інших відповідях), якщо у вас є потреба, ви можете виконувати інші програми з нестандартними змінними середовища, використовуючи 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'
        };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.