Linux环境变量名称中允许的字符

Linux环境变量名称中允许的字符,linux,syntax,environment-variables,Linux,Syntax,Environment Variables,Linux环境变量名中允许哪些字符?我对手册页和web的粗略搜索只产生了关于如何使用变量的信息,但没有提供允许使用哪些名称的信息 我有一个Java程序,它需要一个包含点的已定义环境变量,如com.example.fancyproperty。在Windows中,我可以设置这个变量,但在linux中(在SuSE和Ubuntu中尝试过)我没有运气设置它。这个变量名是允许的吗?我的快速测试表明,它们基本上遵循与C变量名相同的规则,即 a-z,a-z,和0-9 不能以数字开头 所以这就排除了它们内部的。任

Linux环境变量名中允许哪些字符?我对手册页和web的粗略搜索只产生了关于如何使用变量的信息,但没有提供允许使用哪些名称的信息


我有一个Java程序,它需要一个包含点的已定义环境变量,如
com.example.fancyproperty
。在Windows中,我可以设置这个变量,但在linux中(在SuSE和Ubuntu中尝试过)我没有运气设置它。这个变量名是允许的吗?

我的快速测试表明,它们基本上遵循与C变量名相同的规则,即

  • a-z,a-z,
    和0-9
  • 不能以数字开头
  • 所以这就排除了它们内部的
    。任何非法变量名都会被记入
    未知命令


    这是在ZSH中测试的,ZSH主要与BASH兼容。

    这取决于shell。我猜您默认使用的是bash,在这种情况下,字母、数字和下划线是允许的,但变量名不能以数字开头。从Bash v.3开始,.

    取决于您所说的“允许”是什么意思

    忽略当前的窗口:

    环境是一个字符串数组,传递给程序的主函数。如果您阅读execve(2),您将看到除了空终止之外,对这些字符串没有任何要求或限制

    按照惯例,每个字符串由NAME=value组成。没有引用约定,因此在此约定中,名称中不能有“=”

    正常人通过与壳讨论来设置这些字符串。每个shell对于什么是有效变量名都有自己的想法,因此您必须阅读当前shell的手册页才能了解它的想法

    通常,com.basketball.spit=flegh等都是Java系统属性,无论某些Java程序是否愿意退回到环境中,最好使用-D来指定它们。

    From:

    这些字符串具有以下形式: 名称=值名称不应包含 字符“=”。用于指定值 可跨符合以下要求的系统进行移植: IEEE标准1003.1-2001,该值应 由来自 可移植字符集(除NUL外) 和如下所示

    因此名称可以包含除=和NUL之外的任何字符,但是:

    Shell和 IEEE标准实用程序卷 1003.1-2001仅由大写字母、数字和‘‘’组成 (下划线)来自字符 在可移植字符集中定义,以及 不要以数字开头。其他 字符可以由 实施申请书须 容忍这些名字的存在


    因此,虽然名称可能有效,但shell可能不支持字母、数字和下划线以外的任何内容

    壳体部分的POSIX标准 Shell和Tools标准没有定义变量名的词法约定,但只是一个粗略的定义 显示它使用类似于

    [a-zA-Z]+[a-zA-Z0-9\]*

    (编辑:在第二个字符类中添加缺少的下划线。)

    请注意,由于某些Shell不支持正则表达式中的+,因此可能更易于移植的正则表达式可能是:


    [a-zA-Z{1,}[a-zA-Z0-9{0,}

    虽然大多数shell不允许设置环境变量(如其他答案中所述),但如果需要,可以使用
    env(1)
    使用非标准环境变量执行其他程序

    例如,擦除所有环境,并将
    Strange.Env:Var
    设置为value
    foo
    ,然后执行打印它的perl程序:

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

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

    是的,你能做到。

    使用
    exec
    env
    命令实现此场景

    Docker中的测试夹具
    docker run-it--rm alpine:3.10
    
    在容器中运行命令:

    exec env spring.application_name=happy变量名${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添加python
    python-c’导入操作系统;打印(os.environ[“spring.application_name”])
    
    输出为
    happy变量名

    发生了什么事?
  • Shell调用内置exec
  • Shell内置exec调用syscall.exec创建进程“env”以替换当前Shell
  • 环境进程调用syscall.execvp创建进程'/bin/sh'以替换环境进程
  • 另一种方式
    • Docker图像
    如果您使用的是docker,则可以在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应用-f测试。yaml

    验证
    kubectl日志foobar
    输出:

    xx.ff-bar=1234
    

    ConfigMap允许'-'、'.'或'.'

    幸运的是,我发现该程序对Java系统属性(使用
    -D
    命令行选项声明)同样满意,因此它现在可以工作了。显然,程序在两个变量集中都会查找,而不会告诉我。但我仍然很好奇哪些环境变量名是允许的。@AleksandrDubinsky我删除了它。这是类似的,但关于别名定义,不完全是环境变量,如果您使用Spring,然后默认的SystemEnvironmentPropertySource还将查找
    com\u example\u fancyproperty
    com\u example\u fancyproperty
    。我应该更早得出结论,变量的格式类似于Java系统属性,而不是试图将其设置为环境变量。谢谢,艾登。我认为在第二组方括号中缺少一个下划线:它可能应该是:
    [a-zA-Z_][a-zA-Z0-9_]*
    ,对于像我这样认为bash-4.1的引用有点模糊的人(616000)