Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何使bash将未定义的变量视为错误?_Linux_Bash_Shell - Fatal编程技术网

Linux 如何使bash将未定义的变量视为错误?

Linux 如何使bash将未定义的变量视为错误?,linux,bash,shell,Linux,Bash,Shell,请注意:关于如何在此站点上测试单个shell变量,有很多问题。这个问题是关于测试脚本中任何未定义变量的问题 您可以在bash中使用未定义的变量,而不会在执行时看到任何错误: #!/bin/bash echo ${UNDEF_FILE} ls -l ${UNDEF_FILE} exit 0 我发现这很容易出错。如果要更改大型脚本中某个变量的名称,或删除该变量,则所有以前的陈旧引用都会导致脚本中出现错误。有时,这对调试来说是不明显的,或者你发现什么时候太迟了 为什么允许这样做?有没有办法标记未

请注意:关于如何在此站点上测试单个shell变量,有很多问题。这个问题是关于测试脚本中任何未定义变量的问题

您可以在bash中使用未定义的变量,而不会在执行时看到任何错误:

#!/bin/bash

echo ${UNDEF_FILE}
ls -l ${UNDEF_FILE}

exit 0
我发现这很容易出错。如果要更改大型脚本中某个变量的名称,或删除该变量,则所有以前的陈旧引用都会导致脚本中出现错误。有时,这对调试来说是不明显的,或者你发现什么时候太迟了

为什么允许这样做?有没有办法标记未定义的变量?

您可以使用:

set -u
在脚本开始时,在使用未定义变量时引发错误

-u

执行参数扩展时,将未设置的变量和参数(特殊参数“@”和“*”除外)视为错误。如果试图对未设置的变量或参数进行扩展,shell将打印一条错误消息,如果不是交互式的,将以非零状态退出


set-u
是更通用的选项,但正如其他答案的评论中所指出的那样,在编写使用
set-u
的惯用shell脚本时存在问题。另一种方法是创建参数展开式,在未设置特定变量时产生错误

$ echo $foo

$ echo $?
0
$ echo "${foo?:no foo for yoo}"
bash: foo: :no foo for yoo
$ echo $?
1

此错误将导致退出非交互式shell。这为您提供了一种快速的方法来保证错误条件不会允许控制流以未定义的值继续。不需要交互式shell退出,但值得注意的是,即使在交互式shell中,如果函数中发生此错误,bash也会从函数调用返回。

…但是,值得指出的是,此功能的实用性是。。。争议:许多常见的习惯用法依赖于扩展为空字符串的未定义值,因此,如果需要,需要显式编写代码以实现
set-u
兼容性。
set-o nounset
set-u
具有相同的效果(在Bash中),有些人更喜欢它。有关使用
set-u
set-o nounoset
@pjh所引起的常见问题的处理方法,我试图找到有关如何在脚本中使用未定义变量的更多信息,其中
set-u
set-o nounoset
已设置,这个答案非常有用。“为什么?”让我们回到与20世纪70年代外壳的兼容性。如果您关心的是最佳实践,而不是历史,那么静态检查——与也可下载的一样——是您的朋友。坦率地说,使未定义变量的扩展出错将打破许多常见习惯用法<例如,code>[[$var]]&{echo“使用$var做某事”}将与
set-u
中断:与
set-e
(只将未检查或未用作条件的故障转换为故障)不同,
set-u
将对未定义变量的每个引用都设置为错误。(顺便说一句——所有caps变量名都在POSIX为对shell或操作系统有意义的环境变量定义的空间中;包含至少一个小写字符的变量名称空间保留给应用程序使用。由于设置了shell变量与环境变量共享名称(覆盖后者)。顺便问一下,这是编辑吗(“请注意:关于如何在此网站上测试单个shell变量,有很多问题。这个问题是关于测试脚本中任何未定义的变量。”)指向我?如果是这样,我建议你可能误解了我之前的评论。我想说的是,如果使用
set-u
,则
[[[$var]]
不起作用,而不是它是检查单个变量是否未设置的可用机制。同样,对于
[-n“$var”]
[-z“$var”]
等;如果使用
set-u
,则需要一组不同的习惯用法。