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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2821043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:01:00  来源:igfitidea点击:

Allowed characters in Linux environment variable names

linuxsyntaxenvironment-variables

提问by Christian Semrau

What characters are allowed in Linux environment variable names? My cursory search of man pages and the web did only produce information about how to work with variables, but not which names are allowed.

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

I have a Java program that requires an defined environment variable containing a dot, like com.example.fancyproperty. With Windows I can set that variable, but I had no luck setting it in linux (tried in SuSE and Ubuntu). Is that variable name even allowed?

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

采纳答案by Robert Gamble

From The Open Group:

来自开放组

These strings have the form name=value; names shall not contain the character '='.For values to be portable across systems conforming to IEEE Std 1003.1-2001, the value shall be composed of characters from the portable character set (except NUL and as indicated below).

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

So names may contain any character except = and NUL, but:

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

Environment variable names used by the utilities in the Shell and Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase letters, digits, and the '_' (underscore)from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names.

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

So while the names may be valid, your shell might not support anything besides letters, numbers, and underscores.

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

回答by LukeN

My quick testing showed that they basically follow the same rules as C variable names do have, namely

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

  1. a-z, A-Z, _and 0-9
  2. May NOT begin with a number
  1. az、AZ_和 0-9
  2. 不能以数字开头

So this excludes .inside them. Any illegal variable name is credited with unknown command.

所以这不包括.在他们里面。任何非法的变量名都被记为unknown command.

This was tested in ZSH, which is mostly BASH-compatible.

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

回答by ire_and_curses

It depends on the shell. I'm guessing you're using bash by default, in which case letters, numbers and underscores are allowed, but you can't start the variable name with a number. As of Bash v.3, periods are not allowed within variable names.

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

回答by bmargulies

Depends on what you mean by 'allowed'.

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

Ignoring Windows for the nonce:

忽略 Windows 的随机数:

The environment is an array of strings, passed to the main function of a program. If you read execve(2), you will see no requirements or limits on these strings other than null-termination.

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

By convention, each string consists of NAME=value. There is no quoting convention, so you can't have an '=' in the name in this convention.

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

Normal humans set these strings by discussing them with their shell. Each shell has it's own ideas of what are valid variable NAMEs, so you have to read the man page for the shell-of-the-moment to see what it thinks.

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

Generally, things like com.baseball.spit=fleagh are Java system properties, and whether or not some Java program is willing to fall back to the environment, it's better to specify them with -D.

一般像com.baseball.spit=fleagh这样的东西都是Java系统属性,不管有没有Java程序愿意回退到环境,最好用-D来指定。

回答by Aiden Bell

The POSIX standards on shells section of IEEE Std 1003.1-2008 / IEEE POSIX P1003.2/ISO 9945.2Shell and Tools standard doesn't define the lexical convention for variable names, however a cursory look at the sourcereveals it uses something similar to

IEEE Std 1003.1-2008 / IEEE POSIX P1003.2/ISO 9945.2Shell 和工具标准的 POSIX 标准外壳部分 没有定义变量名称的词汇约定,但是粗略地 查看源代码会发现它使用类似于

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

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

(Edit: Added missing underscore in 2nd character class.)

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

A quick note, as some shells don't support the + in regex, a potentially more portable regex may be:

快速说明,由于某些 shell 不支持正则表达式中的 +,因此可能更便携的正则表达式可能是:

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

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

回答by Matija Nalis

While most shell will not allow setting enviroment variables (as mentioned in other answers), if you have need you can execute other programs with nonstandard enviroment variables using env(1).

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

For example, erasing all enviroment and setting Strange.Env:Varto value foo, and executing perl program that prints it:

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

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

will print

将打印

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

回答by Zealic

YES, YOU CAN DO IT.

是的,你可以做到。

Use execand envcommand to implement this scene.

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

Test Fixture in Docker

Docker 中的测试装置

docker run -it --rm alpine:3.10

Run command in container:

在容器中运行命令:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}

Verify environment variables:

验证环境变量:

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=/

Use ps auxto verify PID not changed

使用ps aux验证PID没有改变

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux

Use pythonto verify environemnt variable

使用python验证environemnt变量

apk add python
python -c 'import os; print(os.environ["spring.application_name"])'

OUTPUT is happy-variable-name.

输出是happy-variable-name

What happen?

发生什么事?

  1. Shell call builtin exec
  2. Shell builtin exec call syscall.exec create process 'env' to replace current shell
  3. env process call syscall.execvp create process '/bin/sh' to replace env process
  1. Shell 调用内置 exec
  2. Shell 内置 exec 调用 syscall.exec 创建进程 'env' 来替换当前的 Shell
  3. env 进程调用 syscall.execvp 创建进程 '/bin/sh' 来替换 env 进程

Another way

其它的办法

  • Docker image
  • Docker 镜像

If you are using docker, you can set variable in Dockerfile

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

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Kubernetes configmap
  • Kubernetes 配置图

If you are using kubernetes, you can set variable by ConfigMap

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

test.yaml

测试.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

Deploy pod kubectl apply -f test.yaml

部署 pod kubectl apply -f test.yaml

Verify kubectl logs foobaroutput:

验证kubectl logs foobar输出:

xx.ff-bar=1234

ConfigMap allow '-', '_' or '.'

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