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

Chr*_*rau 133 linux syntax environment-variables

Linux环境变量名称中允许哪些字符?我粗略地搜索手册页和网页只会产生有关如何使用变量的信息,但不会产生允许使用哪些名称的信息.

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

Rob*_*ble 193

来自公开组:

这些字符串的格式为name = value; 名称不得包含字符'='.对于可在符合IEEE Std 1003.1-2001的系统中移植的值,该值应由便携式字符集中的字符组成(NUL除外,如下所示).

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

IEEE Std 1003.1-2001的Shell和Utilities卷中的实用程序使用的环境变量名称仅由大写字母,数字和便携式字符集中定义的字符的"_"(下划线)组成,并且不以数字开头.实现可以允许其他字符; 申请应容忍此类名称的存在.

因此,尽管名称可能有效,但您的shell可能不支持除字母,数字和下划线之外的任何内容.

  • 只是检查:第二个引用是非规范性的:它只是观察到POSIX为它的实用程序定义的特殊变量是`[a-zA-Z _] [a-zA-Z0-9 _]*`(隐含地暗示这个形式)是saner),但实际的规范(引用1)**需要**所有实现支持除了`=`和`NUL`之外的任何东西? (7认同)
  • 此外,"便携式字符集"http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap06.html#tagtcjh_3包含空格和非打印等内容:我们可以使用或不使用这些内容吗? (3认同)
  • 这正是我观察到的。Shell不喜欢将特殊字符用作变量名的一部分。但是,当一个程序或脚本(例如Java或Perl)使用名称中的特殊字符初始化变量并调用另一个可执行文件(子进程)时,后者可执行文件可以毫无问题地访问该变量。 (2认同)
  • @checksum,大写字母是显式指定的变量名称,对 POSIX 指定的工具(包括 shell)有意义;至少包含一个小写字符的名称明确保留供应用程序使用。因此,最佳实践实际上是在应用程序的变量名称中至少包含一个小写字符,以确保您不会无意中覆盖(因为设置 shell 变量将覆盖任何类似名称的环境变量)一个具有以下含义的变量:系统。请参阅http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html (2认同)
  • @CiroSantilli乌坎事件2016六四事件法轮功,可以在环境变量中使用;你*不能*在shell变量中使用它们,并且不能保证可以从shell访问这些环境变量。 (2认同)

Aid*_*ell 33

上壳部分的POSIX标准 IEEE标准1003.1-2008/IEEE POSIX P1003.2/ISO 9945.2 壳牌和工具标准没有定义的变量名词法约定,但粗略 看看源揭示它使用类似的东西

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

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

快速说明,因为有些shell不支持正则表达式中的+,可能更具可移植性的正则表达式可能是:

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

  • 谢谢,艾登.我认为第二组方括号中缺少一个下划线:它可能应该是:`[a-zA-Z _] [a-zA-Z0-9 _]*`对于像我这样找到bash的参考文献的人 - 4.1有点模糊(616'000行代码),这里有一些提示可以找到相关的代码行:`subst.c:param_expand(),在默认情况下` - >`general.h:`/*准确定义合法shell标识符的组成.*/#define legal_variable_starter(c)(ISALPHA(c)||(c =='_'))#define legal_variable_char(c)(ISALNUM(c)|| c =='_') (4认同)
  • 在第一个字符类中不需要该加号。 (3认同)
  • POSIX定义:[3.231名称](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_231)`一个单词,由可移植字符集中的下划线,数字和字母组成.名称的第一个字符不是数字`. (3认同)
  • @scravy是的,虽然我从源代码中获取正则表达式,所以我要保持+. (2认同)

Luk*_*keN 11

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

  1. az,AZ _和0-9
  2. 不能以数字开头

所以这不包括.在他们内心.任何非法变量名称都被记入unknown command.

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


Zea*_*lic 6

是的,你可以做到。

使用execenv命令来实现这个场景。

Docker 中的测试装置

docker run -it --rm alpine:3.10
Run Code Online (Sandbox Code Playgroud)

在容器中运行命令:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}
Run Code Online (Sandbox Code Playgroud)

验证环境变量:

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

使用ps aux验证PID没有改变

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux
Run Code Online (Sandbox Code Playgroud)

使用python验证environemnt变量

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

输出是happy-variable-name

发生什么事?

  1. Shell 调用内置 exec
  2. Shell 内置 exec 调用 syscall.exec 创建进程 'env' 来替换当前的 Shell
  3. env 进程调用 syscall.execvp 创建进程 '/bin/sh' 来替换 env 进程

其它的办法

  • Docker 镜像

如果您使用的是 docker,则可以在 Dockerfile 中设置变量

FROM busybox
ENV xx.f%^&*()$#ff=1234
Run Code Online (Sandbox Code Playgroud)
  • Kubernetes 配置图

如果你使用 kubernetes,你可以通过 ConfigMap 设置变量

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

部署 pod kubectl apply -f test.yaml

验证kubectl logs foobar输出:

xx.ff-bar=1234
Run Code Online (Sandbox Code Playgroud)

ConfigMap 允许“-”、“_”或“.”


ire*_*ses 5

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


bma*_*ies 5

取决于“允许”的含义。

忽略Windows随机数:

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

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

正常人通过与外壳讨论它们来设置这些字符串。每个shell对于有效的变量NAME都有自己的想法,因此您必须阅读一下shell的手册页,以了解其想法。

通常,诸如com.baseball.spit = fleagh之类的东西是Java系统属性,并且无论某些Java程序是否愿意使用该环境,最好使用-D来指定它们。