Експорт змінної з крапкою (.) В ній


38

Як експортувати змінну, яка має в ній крапку. Я отримую "недійсне ім'я змінної", коли я намагався:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Навіть уникнути точки метахарактора (.) Теж не допомогло

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier


1
на жаль, це не вказано, коли я набирав / шукав подібне питання. вибачте. ..
користувач1587504

Відповіді:


49

Принаймні для bashman сторінки визначає синтаксис експорту як:

export [-fn] [name[=word]] ...

Він також визначає "ім'я" як:

   name   A  word  consisting  only  of alphanumeric characters and under
          scores, and beginning with an alphabetic character or an  under
          score.  Also referred to as an identifier.

Отже, ви дійсно не можете визначити змінну типу, my.homeоскільки вона не є дійсним ідентифікатором.

Я дуже впевнений, що ваш ksh має дуже подібне визначення ідентифікатора, і тому він також не дозволяє такого роду змінних. (Подивіться на його довідкову сторінку.)

Я також впевнений, що існує якийсь загальний стандарт (POSIX?) Із зазначенням того, що дозволено як ідентифікатор (а отже, ім'я змінної).


Якщо вам справді потрібна така змінна з певних причин, ви можете використовувати щось подібне

env "my.home=/tmp/someDir" bash

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

perl -e 'print $ENV{"my.home"}'

Наприклад

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

має надрукувати ваш шлях.


Це через інтеграцію мурашок. І, на жаль, це не дозволяє встановити / експортувати змінну з unix. Приймаючи вашу відповідь. ..
користувач1587504

1
ant зазвичай налаштовується однією змінною середовища, яка називається ANT_OPTSабо ~ / .antrc. Немає потреби в самих мурашниках дивні назви змінних середовищ.
michas

8

Хоча змінні середовища можуть мати будь-яке ім'я (включаючи порожню рядок), що не містить знака рівності або нульового байта, оболонки відображають змінні середовища в змінні оболонки, а в більшості оболонок імена змінних обмежуються буквено-цифровими символами ASCII і _там, де перший символ може ' т бути цифрою (для позиційних параметрів і інших спеціальних з них , як , за винятком $*, $-, $@, ..., (які не відображаються у відповідних змінних оточення)). Також зауважте, що деякі змінні зарезервовані / спеціальні оболонкою /.

Винятки з цього:

  • rcОболонки і її похідні , як esі akangaпідтримувати будь-яке ім'я , крім порожнього рядка, і ті, які все-цифрові або містити =символи (і завжди експортувати всі свої змінні середовища, і остерігайтеся спеціальними змінними , такі як *, status, pid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;

    Однак він використовує власне кодування для змінних, ім'я яких не містить alnums або для масивів при передачі в середовище команд, що виконуються:

    $ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
    __2b=zzz$
    __5f_=zzz$
    a=zzz\001xxx$
    $ env +=x rc -c "echo $'+'"
    x
    $ env __2b=x rc -c "echo $'+'"
    x
  • AT & T ksh, yashі zsh(також , bashале тільки для одного байта символів) Підтримка alnums в поточній локалі, не тільки ASCII з них.

    $ Stéphane=1
    $ echo "$Stéphane"
    1

    У цих оболонках ви можете змінити локаль, щоб вважати більшість символів альфа, але все одно це не працюватиме як символи ASCII .. Ви можете обдурити zshабо kshподумати £про букву, але не той .чи будь-який інший символ ASCII (якщо це стосується дозволу символів із змінними іменами, а не для [[:alpha:]]глобуса).

  • ksh93має спеціальні змінні, ім'я яких містить крапку ${.sh.version}, але вони не відображаються на змінні середовища та є спеціальними. Потрібно .переконатися, що він не суперечить іншим змінним. Якби він вирішив викликати його $sh_version, тоді він міг би мати потенційно зламані сценарії, які вже використовували цю змінну (див., Наприклад zsh, проблеми з її $pathабо $commandsспеціальними змінними масиву / хеш (a la csh), які порушують деякі сценарії).

Слід зазначити , що на додаток до оболонках , що не підтримують ці змінні, деякі оболонки , як pdksh / МКШ зробити видалити їх з навколишнього середовища , яку вони отримують ( bashвидаляє один з порожнім ім'ям, ash, kshі bashвидалити ці рядки оточення , які не містять =символів):

$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%

$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%

$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%

Підводячи підсумок, найкраще дотримуватися імен змінних , підтримуваних більшістю оболонок і навіть намагаються використовувати великі букви для змінних оточення (і нижній регістр або змішаний регістр для НЕ експортованих змінних оболонки) уникати тих , які є особливими в оболонках (наприклад IFS, PS1, BASH_VERSION...).

Якщо вам потрібно встановити таку змінну в оболонці, яка не підтримує їх, але не відкидає їх, ви можете або заново виконати щось, наприклад:

#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"

(очевидно, якщо вам потрібно зробити це в середині сценарію, це не допоможе, але ви зможете переглянути цей підхід для збереження та відновлення середовища виконання оболонки протягом повторного виконання). Або спробуйте підхід налагодження:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"

(Що один , здається, працює з zsh, yash, cshі tcshна Linux amd64, але не з якоюсь - або з інших оболонок я спробував ( mksh, ksh93, bash, dash)).


1
mkshpdksh) дійсно побудувати процеси, які вони нерестують, отримують повністю з нуля, використовуючи лише ті параметри, експортовані в поточне середовище виконання оболонки, тому немає можливості передати ці змінні через ці оболонки. (Зверніть увагу, що передані змінні можуть змінюватися; наприклад, я планую підтримати експорт масиву на mkshякийсь день.)
mirabilos

0

Як зазначають інші повідомлення, найпоширеніші оболонки не дозволяють встановлювати змінні середовища з періодами в імені. Однак я виявив ситуації, зокрема із залученням Докера та запрошених програм, де програмне забезпечення вимагало ключових значень з періодами.

Однак у кожній з цих ситуацій ці пари ключ-значення могли бути передані програмі іншими засобами, ніж просто змінні середовища. Наприклад, в Ant ви можете використовувати "-propertyfile (ім'я файлу)" для передачі у файл властивостей, відформатований набір ключових значень. Confd дозволяє "-backend file -file (файл yaml)".

Я передав змінні середовища у формі "C__any_value = 'my.property.key = значення'". Потім я переключив виклик програми, щоб спершу створити файл:

set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt

setКоманда, в Борне Shell, буде виводити кожне властивість в окремому рядку у вигляді

C__any_value='my.property.key=the value'

awkКоманда буде обробляти тільки ті змінні оточення , починаючи з C__, а потім витягти значення , що містяться в одинарних лапках.

Цей метод вимагає встановити значення змінної середовища в точній формі, якої вимагає програма обробки. Крім того, якщо значення вашого ключа або ключ міститимуть одинарні лапки, вам потрібно буде змінити символ роздільника поля awk на те, що ви знаєте, що не з’явиться, і оточити значення цим символом. Наприклад, використовувати %як роздільник:

$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value

(точний вихід буде залежати від вашої оболонки.) Вам потрібно буде вжити додаткових кроків, щоб розшифрувати відхилення цитати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.