是否在脚本中定义了未设置的全局变量的良好实践?

时间:2012-10-21 14:03:12

标签: bash sh

在编写sh脚本时,在脚本末尾取消设置所有先前定义的全局变量是不是一种良好的做法?

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

. myscript

执行脚本后,shell会使用脚本中定义的变量进行操作。这似乎非常糟糕(特别是如果被其他人使用)。

如果可以,我会完全摆脱sh(或bash)中的全局变量,但更常见的是它们不是最差的解决方案: - )。

3 个答案:

答案 0 :(得分:10)

这并不是真正执行脚本。它正在寻找它,这使得shell在脚本中执行每个命令。如果要执行脚本,可以执行以下操作:

./myscript

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

如果您确实需要获取脚本,以便它可以执行诸如设置环境变量或更改当前目录之类的操作,那么您可以使用括号隔离子shell中的变量:

(
  a=7
  echo $a
)
# The change in a doesn't get to here

如果要取消设置使用的变量,则会出现相反的问题。如果用户设置了具有相同名称的变量,那么最终会将其销毁。

答案 1 :(得分:2)

  

在编写sh脚本时,在脚本末尾取消设置所有先前定义的全局变量是不是一种良好的做法?

如果脚本正常执行(在子shell中,使用myscript),则没有理由担心脚本中定义的变量(或函数);当脚本停止执行而没有对调用shell造成任何损坏时,它们就会消失。

  

例如,如果我使用内置的.source)执行我的脚本myscript,就像这样

. myscript
     

执行脚本后,shell会被脚本中定义的变量污染。这似乎非常糟糕(特别是如果被其他人使用)。

任何来源的脚本都需要有充分的理由来源(设置特定的环境变量或更改目录是通常的原因)。其他人将使用的任何此类脚本都应该对于设置其偶然设置的任何变量感到狂热,首先要小心使用特别命名的变量,并在完成时将它们全部取消。

或者,至少,如果它用变量填充我的shell,我将不会采购其他人的脚本。我不经常在'profile'操作之外获取文件,但是当我这样做时,脚本被设计为设置某些变量。它可以设置那些(如果没有那就没用);但最好不要添加随机分类的其他变量。如有必要,我会复制另一个人的脚本并对其进行消毒以供我自己使用,或者使用消毒脚本进行包装。

我有一个用于设置PATH的脚本(所以它或多或少必须来源才有用)。它开始了:

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)

此处,命令的输出用作PATH的新值。当您只需要设置一个变量时,这是一个可行的设计。如果您需要设置一组环境变量(例如,将环境配置为使用特定的DBMS),则不太可行。

我不会使用普通脚本清理变量 - 那些不打算获取的脚本。但对于可源代码的脚本,我认为这很重要。我怀疑每个人都同意我的意见;很多人可能不在乎。但我同意你的观点 - 源代码脚本很干净很重要。

答案 2 :(得分:1)

不一定。

当你执行一个脚本时,它会执行一个新的shell,并且任何变量都会设置该脚本不会影响父shell。

如果你在shell本身上做. myscript(而不是在脚本中),那么变量集将处于活动状态并且可能会像你所说的那样污染shell。