Bash 如果标志值包含括号,则getops$OPTARG为空
当我将包含Bash 如果标志值包含括号,则getops$OPTARG为空,bash,echo,getopts,Bash,Echo,Getopts,当我将包含[…]的标志传递给bash脚本时,getops会在我尝试使用$OPTARG获取值时给我一个空字符串 shopt -s nullglob while getopts ":f:" opt; do case $opt in f) str=$OPTARG ;; esac done echo ${str} 运行脚本: $ script.sh -f [0.0.0.0] <blank line> $script.sh-f[0.0.0.0] 如何
[…]
的标志传递给bash脚本时,getops
会在我尝试使用$OPTARG
获取值时给我一个空字符串
shopt -s nullglob
while getopts ":f:" opt; do
case $opt in
f)
str=$OPTARG
;;
esac
done
echo ${str}
运行脚本:
$ script.sh -f [0.0.0.0]
<blank line>
$script.sh-f[0.0.0.0]
如何将原始值返回到脚本中?假设在较大的脚本中需要
shopt-s nullglob
。您可以使用
shopt-u nullglob
临时禁用shopt-s nullglob
shopt -s nullglob
shopt -u nullglob
while getopts ":f:" opt; do
case $opt in
f)
str=$OPTARG
;;
esac
done
echo ${str}
shopt -s nullglob
简短摘要:双引号引用变量引用。和使用 详细说明:当使用一个不带双引号的变量(例如,
echo${str}
)时,shell会尝试将其值拆分为单词,并将任何看起来像通配符表达式的内容展开为匹配文件的列表。对于[0.0.0.0]
,括号使其成为通配符表达式,将匹配字符“0”或“.”(相当于[0.]
)。如果您有一个名为“0”的文件,它将扩展到该字符串。如果没有匹配的文件,它通常不会展开,但如果设置了nullglob
它将展开为。。。空
如果没有匹配的文件,关闭nullglob
可以解决问题,但这并不是正确的方法。我记得(但现在找不到)我们有一个问题,关于一个脚本,它在一台特定的计算机上失败了,结果是一台计算机碰巧有一个文件,它与一个不带引号的变量值中的括号表达式相匹配
正确的解决方案是在变量引用周围加双引号。这告诉shell跳过分词和通配符扩展。下面是一个交互式示例:
$ str='[0.0.0.0]' # Quotes aren't actually needed here, but they don't hurt
$ echo $str # This works without nullglob or a matching file
[0.0.0.0]
$ shopt -s nullglob
$ echo $str # This fails because of nullglob
$ shopt -u nullglob
$ touch 0
$ echo $str # This fails because of a matching file
0
$ echo "$str" # This just works, no matter whether file(s) match and/or nullglob is set
[0.0.0.0]
因此,在脚本中,只需将最后一行更改为:
echo "${str}"
请注意,case$opt-in
或str=$OPTARG
都不需要双引号,因为这些特定上下文中的变量不需要进行分词或通配符扩展。但在我看来,跟踪哪些上下文是安全的,不使用双引号比它的价值要麻烦得多,你应该把它们都双引号
顺便说一句,他善于发现这样的常见错误;我建议您通过它输入脚本,因为这可能不是您遇到此问题的唯一地方。bash脚本应该以
开头/bin/bash
-将这一行添加到脚本时发生了什么?请注意,当我执行脚本时,我得到了以下输出:[0.0.0.0]
我找到了原因,但不知道如何处理它。脚本要大得多,这只是一小部分。顶部有一个shopt-s nullglob
。这破坏了脚本。假设需要shopt-s nullglob
,您可以在运行代码的一小部分时禁用它。在代码的一小部分之前添加shopt-u nullglob
,在代码之后添加shopt-s nullglob
时发生了什么?我可以将其放在flag switch语句之后,但不能放在echo命令之后。我一输入shopt-s nullglob
变量的计算结果就是空字符串。这是一个非常好的深入回答!然而,您提出的解决方案看起来与我已有的解决方案一模一样。(见我代码块的最后一行)@Gilrich D'Oh!在复制了原始行之后,我完全忘记了实际应用修复。我编辑了它以更正。。。