如果我从变量中删除导出,还有什么会中断?

TCZ*_*CZ8 5 shell-script environment-variables variable

我的问题是,当我开始编写脚本时,我遇到了几个变量作用域问题,这导致了导出几乎所有变量的坏习惯。

现在我的代码已经变得非常大,我正在考虑清理它,其中一部分是删除一堆无用的导出。不幸的是,我不确定我对变量范围的了解是否完整。即使在阅读了有关该主题的几页之后。

我所知道的(希望是对的):

1-导出变量使其内容可用于子shell进程:

export myvar="content"
Run Code Online (Sandbox Code Playgroud)

2-像这样在括号中完成的内容将受到删除导出的影响(据我所知,这是声明/使用子shell的唯一方法):

$(grep "content" <<< $myvar)
Run Code Online (Sandbox Code Playgroud)

3-变量声明没有设置其作用域是全局的:

myvar="content"
Run Code Online (Sandbox Code Playgroud)

4-因为我没有声明任何局部变量,所以我不必担心在我的函数中引起问题:

local myvar="i don't use this"
Run Code Online (Sandbox Code Playgroud)

问题:

1- 继续删除我的代码旁边的无用导出而不是明显的 noobishness 有什么意义吗?

2-如果我继续进行,还有什么我应该注意的可能会受到影响并破坏我的代码吗?还是我的知识有误/不完整?

3- 如果你知道一个写得很好的(和完整的)变量范围参考,请分享链接。

mik*_*erv 2

只要您不使用export两次评估,您就可以删除所有导出,而不会对导出的变量产生任何影响。两次评估我的意思是:

var1=var2 
export "${var1}=var3"
echo "$var2"
var3
Run Code Online (Sandbox Code Playgroud)

相反,只需使用:

set -a 
Run Code Online (Sandbox Code Playgroud)

...在脚本的顶部。此后定义的所有变量都将自动exported- 其中包括您以前可能没有export编辑过的变量。或者,您可以只set -a使用脚本的一部分,然后set +a取消设置它 - 它也可以作为函数使用。

但子 shell 无论如何都会自动继承变量值,所以:

var1=value
( echo "$(echo "$var1")" )
value
Run Code Online (Sandbox Code Playgroud)

export在这种情况下没有什么区别。

但是,如果您的脚本调用另一个脚本或解释您编辑的值的任何其他可执行文件,export并且您停止调用export它们,那么这些值将不再在其环境中可用。在下面的示例中,我使用 shell 变量$PS1(定义交互式 shell 提示的内容)来演示exported 变量的变化如何影响子进程。

export PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i

###OUTPUT###

this is another executable
 > exit
exit
Run Code Online (Sandbox Code Playgroud)

但 ...

PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i

###OUTPUT###

sh-4.3$ exit
exit
Run Code Online (Sandbox Code Playgroud)

但话又说回来,如果您在调用进程时显式声明环境变量......

PS1="$(printf "this is another executable\n > ")"
{
echo exit | PS1=$PS1 sh -i
echo exit | sh -i
}

###OUTPUT###

this is another executable
 > exit
exit
sh-4.3$ exit
exit
Run Code Online (Sandbox Code Playgroud)