Экспорт переменной с точкой (.) в нем

Вот решение для жемчуга. Этот сценарий обнаруживает [ entryN ] строки и изменения, выходной файл соответственно, но не проверяет, анализирует или обрабатывает данные в каждом разделе, это просто, печатают входную строку к выходному файлу.

#! /usr/bin/perl 

# default output file is /dev/null - i.e. dump any input before
# the first [ entryN ] line.

$outfile='/dev/null';
open(OUTFILE,">",$outfile) || die "couldn't open $outfile: $!";

while(<>) {
  # uncomment next two lines to optionally remove comments (starting with
  # '#') and skip blank lines.  Also removes leading and trailing
  # whitespace from each line.
  # s/#.*|^\s*|\s*$//g;
  # next if (/^$/)

  # if line begins with '[', extract the filename
  if (m/^\[/) {
    (undef,$outfile,undef) = split ;
    close(OUTFILE);
    open(OUTFILE,">","$outfile.txt") || die "couldn't open $outfile.txt: $!";
  } else {
    print OUTFILE;
  }
}
close(OUTFILE);
39
05.10.2013, 01:40
3 ответа

По крайней мере, для bash страница справочника определяет синтаксис экспорта как:

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 -e 'print $ENV{"my.home"}'

Например,

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

должен распечатать Ваш путь.

50
27.01.2020, 19:35
  • 1
    Это из-за в интеграции муравья. И к сожалению это не позволяет устанавливать/экспортировать переменную от Unix. Принятие Вашего ответа... –  user1587504 04.10.2013, 10:40
  • 2
    обычно настраивается названной переменной единой среды ANT_OPTS или ~/.antrc. Никакая потребность в странной переменной среды не называет для самого муравья. –  michas 04.10.2013, 14:18

В то время как переменные среды могут иметь любое имя (включая пустую строку) не содержащий знак "равно" или пустой байт, переменные среды карты оболочек для окружения переменных и в большинстве оболочек, имена переменной ограничены 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 специальные переменные массива/хеша (а-ля csh), которые повреждают некоторые сценарии).

Обратите внимание, что в дополнение к оболочкам, не поддерживающим те переменные, некоторые оболочки как pdksh/mksh действительно удаляют их из среды, которую они получают (bash удаляет тот с пустым названием, ash, ksh и bash удалите те строки среды, которые не содержат a = символ):

$ 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)).

8
27.01.2020, 19:35
  • 1
    mkshpdksh) действительно создайте процессы среды, которые они порождают, добираются полностью с нуля, с помощью только те параметры, экспортируемые в текущей среде выполнения оболочки, таким образом, нет никакого способа передать те переменные через те оболочки. (Обратите внимание, что переменные, которые передаются, подвержены изменениям; например, я планирую поддерживать экспорт массива для mksh однажды.) –  mirabilos 27.02.2014, 16:10

Как указано в других сообщениях, наиболее распространенные оболочки не позволяют устанавливать переменные среды с точками в имени. Однако я сталкивался с ситуациями, особенно с Docker и вызываемыми программами, когда программному обеспечению требовались значения ключей с точками.

Однако в каждой из этих ситуаций эти пары ключей -значений могут быть переданы в программу с помощью других средств, а не только переменных среды. Например, в Ant вы можете использовать «-файл свойств (имя файла )» для передачи отформатированного набора значений ключей -в файле свойств. Confd позволяет использовать «-бэкэнд-файл -файл (файл yaml )».

Я передал переменные окружения в виде "C __любое _значение='my.property.key=значение'". Затем я переключил вызов программы, чтобы сначала сгенерировать файл :

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

Команда setв оболочке Borne выводит каждое свойство в отдельной строке в виде

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

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

2
27.01.2020, 19:35

Теги

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