导出带有点 (.) 的变量

use*_*504 50 shell ksh environment-variables

如何导出带有点的变量。当我尝试时,我得到“无效的变量名”:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name
Run Code Online (Sandbox Code Playgroud)

即使转义元字符点 (.) 也无济于事

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier
Run Code Online (Sandbox Code Playgroud)

mic*_*has 61

至少对于bash手册页将导出语法定义为:

export [-fn] [name[=word]] ...
Run Code Online (Sandbox Code Playgroud)

它还将“名称”定义为:

   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.
Run Code Online (Sandbox Code Playgroud)

因此你真的不能定义一个变量,my.home因为它不是有效的标识符。

我很确定你的 ksh 有一个非常相似的标识符定义,因此也不允许这种变量。(看看它的手册页。)

我也很确定有某种通用标准(POSIX?)指定,允许作为标识符(以及变量名)的内容。


如果由于某种原因你真的需要这种变量,你可以使用类似的东西

env "my.home=/tmp/someDir" bash
Run Code Online (Sandbox Code Playgroud)

无论如何定义它。但话又说回来,您将无法使用正常的 shell 语法访问它。在这种情况下,您可能需要另一种语言,如 perl:

perl -e 'print $ENV{"my.home"}'
Run Code Online (Sandbox Code Playgroud)

例如

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'
Run Code Online (Sandbox Code Playgroud)

应该打印你的路径。

  • ant 通常由一个名为“ANT_OPTS”的环境变量或 ~/.antrc 来配置。ant 本身不需要奇怪的环境变量名称。 (2认同)

Sté*_*las 10

虽然环境变量可以有任何不包含等号或空字节的名称(包括空字符串),但 shell 将环境变量映射到 shell 变量,并且在大多数 shell 中,变量名称仅限于 ASCII 字母数字字符,_并且第一个字符可以t 是一个数字(除了位置参数和其他特殊参数,如$*, $-, $@, ..., (它们没有映射到相应的环境变量))。另请注意,某些变量是由 shell保留/特殊的。

例外情况:

  • rc外壳及其衍生物喜欢esakanga支持任何名称,除了空字符串,和那些所有数字或含有=字符(始终所有的变量导出到环境和特殊变量提防喜欢*statuspid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;
    
    Run Code Online (Sandbox Code Playgroud)

    但是,当在正在执行的命令的环境中传递时,它对名称不包含 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
    
    Run Code Online (Sandbox Code Playgroud)
  • AT&T ksh, yashand zsh(也bash仅适用于单字节字符)支持当前语言环境中的 alnums,而不仅仅是 ASCII 的。

    $ Stéphane=1
    $ echo "$Stéphane"
    1
    
    Run Code Online (Sandbox Code Playgroud)

    在这些 shell 中,您可以更改语言环境以将大多数字符视为字母,但这仍然不适用于.. 你可以愚弄zshksh认为£是一个字母,而不是那个.或任何其他 ASCII 字符(在变量名称中允许字符是相关的,例如不是[[:alpha:]]glob)。

  • ksh93具有名称中包含一个点的特殊变量${.sh.version},但这些变量未映射到环境变量并且是特殊的。这.是为了确保它不与其他变量冲突。如果它选择调用它$sh_version,那么它可能会破坏已经使用该变量的脚本(例如,请参阅zsh$path$commands特殊数组/哈希变量(a la csh)如何破坏某些脚本)。

请注意,除了不支持这些变量的 shell 之外,一些 shell(如 pdksh/mksh)确实它们从它们接收的环境中bash删除(删除名称为空的ashkshbash删除那些不包含=字符的环境字符串):

$ 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 %%%
%%%
Run Code Online (Sandbox Code Playgroud)

总而言之,最好坚持使用大多数 shell 支持的变量名,甚至尝试对环境变量使用大写(对于未导出的 shell 变量使用小写或混合大小写),避免使用 shell 中的特殊变量(如IFS, PS1, BASH_VERSION……)。

如果您确实需要在不支持它们但不丢弃它们的 shell 中设置这样的变量,您可以重新执行自己,例如:

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

(当然,如果你需要做的是在脚本中,这不会帮助,但你可以再看看这种方法来保存并在重新执行中恢复shell执行环境)。或尝试调试器方法:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
Run Code Online (Sandbox Code Playgroud)

(一个似乎与工作zshyashcshtcsh在Linux AMD64,但不与任何其它shell我想(的mkshksh93bashdash))。