4

在编写 sh 脚本时,在脚本末尾取消设置所有先前定义的全局变量是否被认为是一种好习惯?

例如,如果我myscript使用 . (来源)内置,像这样

. myscript

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

如果可以的话,我会完全摆脱 sh(或 bash)中的全局变量,但更多时候它们不是最糟糕的解决方案 :-)。

4

3 回答 3

10

这并不是真正执行脚本。它正在采购它,这使得 shell 执行脚本中的每个命令。如果你想执行脚本,你可以这样做:

./myscript

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

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

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

如果你要取消设置你使用的变量,你会遇到相反的问题。如果用户设置了具有相同名称的变量,那么您最终将销毁它。

于 2012-10-21T14:08:21.213 回答
2

在编写 sh 脚本时,在脚本末尾取消设置所有先前定义的全局变量是否被认为是一种好习惯?

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

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

. myscript

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

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

或者,至少,如果它在我的 shell 中乱扔变量,我不会获取其他人的脚本。我不经常在“配置文件”操作之外获取文件,但是当我这样做时,脚本旨在设置某些变量。它可以设置那些(如果没有它就没有用);但最好不要随意添加其他变量。如有必要,我会复制其他人的脚本并对其进行清理以供我自己使用,或者用清理脚本将其包装起来。

我有一个用于设置 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),那么这是不太可行的。

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

于 2012-10-21T14:38:08.493 回答
1

不必要。

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

如果您. myscript仅在 shell 本身(而不是在脚本内部)上进行操作,那么变量集将是活动的,并且可能会污染 shell,如您所说。

于 2012-10-21T14:07:03.960 回答