在脚本末尾删除所有变量是一个好习惯吗?

Kos*_*hur 1 shell bash shell-script rm variable

在脚本末尾删除 shell 脚本中使用的变量是否好。

rm -rf $abc
rm -rf $def
Run Code Online (Sandbox Code Playgroud)

或者

unset $abc
unset $def
Run Code Online (Sandbox Code Playgroud)

等等。

这实际上是一个好习惯吗?

Mic*_*mer 23

这是一个非常糟糕的做法。

rm删除文件。这与变量无关。在任何情况下,当脚本结束并且操作系统回收 shell 的内存时,变量本身将被处理掉。


在简单的情况下,此构造将删除与其中一个变量的值同名的文件:

abc=filename
rm -f $abc  # Deletes "filename" in the current directory
Run Code Online (Sandbox Code Playgroud)

它变得更糟。如果abcdef包含以空格(或任何其他字符IFS分隔的单个单词的文件名,您将删除这些文件,并且*如果它们出现在任何单词中,通配符也会被扩展。

abc='hello world'
rm -f $abc  # Deletes file "hello" and "world" (leaves "hello world" alone)
abc='5 * 3'
rm -f $abc  # Deletes all files, because * is expanded (!)
def='-r /'
rm -f $def  # Really deletes *all* files this user can access
Run Code Online (Sandbox Code Playgroud)

Shell 参数扩展 with$var受分词影响,其中IFS变量的每个字符将变量分成不同的参数。每个字是然后受到文件名扩展,其用途*?以及[abc...]图案来创建文件名。这可能会变得非常糟糕,这取决于您的变量中有什么。不要这样做。


无需以任何方式在 shell 脚本的末尾清空或取消设置变量。


ilk*_*chu 9

我想知道你的意思是 shell 变量还是临时文件。

如果你正在做的是这个(一个临时文件):

tmp=$(mktemp)
something > "$tmp"
something else < "$tmp"
rm "$tmp"
Run Code Online (Sandbox Code Playgroud)

然后当然,在完成后继续删除临时文件。虽然如果脚本在中间崩溃,文件将留在那里,但这也并不罕见。trap 'rm "$tmp"' EXIT如果您关心,您可以在 shell 退出时删除该文件。

但我没有看到使用 的理由-f,更不用说-rrm这里了。

(另外,请记住引用该变量,即使mktemp默认情况下会生成“漂亮”的文件名。)


但是,如果您这样做(一个变量):

read var
do something with "$var"
rm "$var"
Run Code Online (Sandbox Code Playgroud)

那么您不想这样做:您没有要删除的文件,只有用户输入的内容。当 shell 退出时,shell 变量不再存在,因此无需取消设置它们。


但是,如果您的脚本打算来自另一个 shell(或者它在 .bashrc或类似的 shell 中),则当您的脚本结束时,shell 不会退出。在这种情况下,它可能对unset您最后使用的任何临时变量很有用,不要在 shell 的剩余生命周期内设置它们。

# in .bashrc
__hour=$(date +%H)
if [ "$__hour" -lt 12 ] ; then echo "Good Morning!" ; 
elif [ "$__hour" -gt 18 ] ; then echo "Good Evening!" ;
fi
unset __hour
Run Code Online (Sandbox Code Playgroud)

变量名称可能仍会与该脚本之外使用的某些变量发生冲突,因此命名时必须小心。