Bash 脚本中定义的取消设置全局变量是否是良好的做法?

Bash 脚本中定义的取消设置全局变量是否是良好的做法?,bash,sh,Bash,Sh,在编写sh脚本时,在脚本末尾取消设置所有先前定义的全局变量是否被视为良好做法 例如,如果我使用脚本执行脚本myscript。(来源)内置的,像这样 . myscript . myscript 执行脚本后,shell将使用脚本中定义的变量进行处理。这看起来真的很糟糕(尤其是被其他人使用时) 如果可以的话,我会在sh(或bash)中完全去掉globals,但通常情况下它们不是最差的解决方案:-)。不一定 当您执行脚本时,它将执行一个新的shell,并且任何变量都将其设置为脚本不会影响父shell

在编写sh脚本时,在脚本末尾取消设置所有先前定义的全局变量是否被视为良好做法

例如,如果我使用脚本执行脚本
myscript
。(来源)内置的,像这样

. myscript
. myscript
执行脚本后,shell将使用脚本中定义的变量进行处理。这看起来真的很糟糕(尤其是被其他人使用时)

如果可以的话,我会在sh(或bash)中完全去掉globals,但通常情况下它们不是最差的解决方案:-)。

不一定

当您执行脚本时,它将执行一个新的shell,并且任何变量都将其设置为脚本不会影响父shell


如果您执行
。myscript本身(而不是脚本内部)上的myscript,只有这样,变量集才是活动的,并且可能会像您所说的那样污染shell。

这并不是真正执行脚本。它是源代码,这使得shell执行脚本中的每个命令。如果要执行脚本,请执行以下操作:

./myscript
在这种情况下,脚本中设置的任何环境变量都不会对shell产生影响

如果确实需要为脚本提供源代码,以便它可以执行诸如设置环境变量或更改当前目录之类的操作,则可以使用括号隔离子shell中的变量:

(
  a=7
  echo $a
)
# The change in a doesn't get to here
如果要取消设置所使用的变量,则会出现相反的问题。如果用户设置了一个同名的变量,那么您将最终销毁它

在编写sh脚本时,在脚本末尾取消设置所有先前定义的全局变量是否被视为良好做法

如果脚本正常执行(在子shell中,使用
myscript
),那么就没有理由担心脚本中定义的变量(或函数);当脚本停止执行且不会损坏调用shell时,它们将消失

例如,如果我使用内置的
source
)执行脚本myscript,如下所示

. myscript
. myscript
执行脚本后,shell被脚本中定义的变量污染。这看起来真的很糟糕(尤其是被其他人使用时)

任何源代码脚本都需要有一个很好的源代码理由(设置特定的环境变量或更改目录是常见的原因)。其他人将要使用的任何这样的脚本都应该热衷于取消设置它附带设置的任何变量,首先要小心使用命名不同的变量,并在完成时取消所有变量的设置

或者,至少,如果其他人的脚本在我的shell中堆满了变量,我就不会为其提供源代码。我不经常在“profile”操作之外生成源文件,但当我这样做时,脚本设计用于设置某些变量。它可以设置这些(如果不设置,则不会有用);但最好不要随机添加其他变量。如果有必要,我会复制另一个人的脚本并对其进行消毒以供自己使用,或者用消毒脚本将其包装起来

我有一个用于设置路径的脚本(所以它或多或少都需要源代码才能有用)。它开始于:

ps_machine=$(uname -n)
ps_pathset=no
ps_pathoptsfile=
for ps_file in \
        ${HOME}/.pathopts.$ps_machine \
        ${REAL_HOME:-$HOME}/.pathopts.$ps_machine \
        ${HOME}/.pathopts \
        ${REAL_HOME:-$HOME}/.pathopts
do
    ...40 lines of esoteric code...
    ...some set ps_perl; some set ps_pathopts...
done

...5 lines of active code that set PATH...

unset ps_pathset ps_pathoptsfile ps_pathopts ps_file ps_perl ps_machine
我这样说是因为:

. mcpathset
此命令的替代设计为:

export PATH=$(mcpathset)
这里,命令的输出用作路径的新值。当您只需要设置单个变量时,这是一种可行的设计。如果您需要设置一组环境变量(例如,配置环境以使用特定的DBMS),那么这就不太可行

我不会用普通的脚本清理变量,这些脚本不是用来源代码的。但是对于源代码脚本,我认为这很重要。我怀疑每个人都同意我的观点;很多人可能根本不在乎。但我同意你的看法——重要的是源代码脚本要干净