我在zsh中声明了两个PATHS。这是怎么发生的?或者我怎样才能重现它?
~ ❯ env | grep -i path
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/bin:/usr/texbin
PATH=/usr/bin:/bin:/usr/sbin:/sbin
答案 0 :(得分:4)
有很多方法可以重现这个输出。
使用换行符进行美化:
% export foo=$'1\nfoo=2'
% env | grep foo
foo=1
foo=2
美观地回车:
export foo=1
export bar=$'2\rfoo'
美观地使用不可打印的字符:
env foo=1 $'foo\x01=2' zsh
但最有趣和最有趣的方法是使用相同的名称实际设置多个变量。
人们通常不会意识到环境根本不包含变量。它只是一个常规但不一定被解释为key=value
对的任意字符串列表。
我们可以简单地添加两个字符串foo=1
和foo=2
,然后由程序决定如何解释它。这样做的一种方法是小型C程序:
int main() {
char *argv[] = { "zsh", 0 };
char *envp[] = { "foo=1", "foo=2", 0 };
execvpe("zsh", argv, envp);
}
执行时,我们将两个值设置为shell:
% env | grep foo
foo=1
foo=2
您可以检查env -0 | od -c
的输出,看看您目前遇到的上述哪一项。
作为奖励,我们会zsh
和bash
询问$foo
在% echo $foo
1
% bash -c 'echo $foo'
2
被发现两次时的价值:
zsh
他们每个人都从环境中挑选一个不同的字符串。
想象一下,如果安全性取决于bash
脚本的sudo
包装器过滤环境变量!
这是为什么不应该尝试重新发明{{1}}的众多原因之一。