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

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

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

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

我所知道的(希望是正确的):

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

export myvar="content"

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

$(grep "content" <<< $myvar)

3-未设置其范围而声明的变量是全局的:

myvar="content"

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

local myvar="i don't use this"

问题:

1-除了我的代码没有散发出明显的新手气息之外,继续删除无用的导出还有什么意义吗?

2-如果我继续这样做,还有什么我应该注意的可能会受到影响并破坏我的代码的事情吗?或者我的知识有错误/不完整吗?

3-如果您知道写得好的(且完整的)变量范围参考,请分享链接。

答案1

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

var1=var2 
export "${var1}=var3"
echo "$var2"
var3

相反,只需使用:

set -a 

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

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

var1=value
( echo "$(echo "$var1")" )
value

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

但 ...

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

###OUTPUT###

sh-4.3$ exit
exit

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

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

相关内容