Linux下的环境变量到底有什么限制?
前言
最近在排查一个eureka问题,发现客户设置了环境变量eureka.client.serviceUrl.defaultZone
。
于是在本地尝试复现这个现场,发现我设置不了这个环境变量,提示:
1 | # export eureka.client.serviceUrl.defaultZone=http://localhost:8761/ |
但是在k8s中,可以给pod设置带点的环境变量。
于是看了下Linux中环境变量的限制。
首先看一下为什么export会报错
以busybox为例,export是一个内置命令,所以执行这个命令的时候,直接调用了 exportcmd
函数。
这个函数的核心逻辑就是:
1 | // 函数setvar |
仔细观察endofname的逻辑就会发现,shell对于环境变量名字的限制是:
- 只能以字母开头
- 只能包含字母和数字
这样一看,eureka.client.serviceUrl.defaultZone
这个环境变量名不符合上述要求的,所以报错。
但是为什么k8s可以设置这个环境变量成功呢?
以为k8s调用的是系统调用 setenv。
setenv
对name的要求很简单,不为NULL,不是空字符串就可以。所以k8s可以设置带点的环境变量。
env命令同样使用的是setenv系统调用,我们用env命令试一试:
1 | # env -i "a.b.c=123" "a b c=123" " =123" sh -c "env" |
可以发现,名字是空格、包含空格、包含点的环境变量,都可以设置成功。
总结
内核对环境变量没有做太多限制,但是shell为了防止出错,做了一些限制。
作为开发者,为了方便最终用户使用,还是尽可能遵守shell的环境变量限制比较好。
Linux下的环境变量到底有什么限制?