bash 为什么我会收到“一元运算符预期”错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19691082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why am I getting a 'unary operator expected' error?
提问by Luke
I'm writing a shell script to streamline my development workflow.
我正在编写一个 shell 脚本来简化我的开发工作流程。
It takes an argument as to which theme folder I'm going to be working in and starts grunt watch
on that directory.
它需要一个关于我将在哪个主题文件夹中工作并从grunt watch
该目录开始的参数。
If I call the script without the necessary argument I'm currently printing a warning that a theme needs to be specified as a command line argument.
如果我在没有必要参数的情况下调用脚本,我目前正在打印一个警告,提示需要将主题指定为命令行参数。
I'd like to print a list of the available options, e.g. theme directories
我想打印可用选项的列表,例如主题目录
This is what I have so far...
这是我到目前为止...
THEME=
if [ $THEME == '' ]
then
echo 'Need to specify theme'
else
cd 'workspace/aws/ghost/'$THEME'/'
grunt watch
fi
Ideally I'd replace the output of the echo
line with an ls
of the themes parent directory like so
理想情况下,我会像这样用主题父目录替换该echo
行的输出ls
THEME=
if [ $THEME == '' ]
then
echo 'Need to specify theme from the following'
ls workspace/aws/ghost
else
cd 'workspace/aws/ghost/'$THEME'/'
grunt watch
fi
However this gives me the following error
但是,这给了我以下错误
./ghost_dev.sh: line 3: [: ==: unary operator expected
回答by Mark Reed
You need quotes around $THEME
here:
你需要$THEME
这里的报价:
if [ $THEME == '' ]
Otherwise, when you don't specify a theme, $THEME
expands to nothing, and the shell sees this syntax error:
否则,当您不指定主题时,$THEME
将展开为空,并且 shell 会看到以下语法错误:
if [ == '' ]
With quotes added, like so:
添加引号,如下所示:
if [ "$THEME" == '' ]
the expansion of an empty $THEME
yields this valid comparison instead:
一个空的扩展会$THEME
产生这个有效的比较:
if [ "" == '' ]
This capacity for runtime syntax errors can be surprising to those whose background is in more traditional programming languages, but command shells (at least those in the Bourne tradition) parse code somewhat differently. In many contexts, shell parameters behave more like macros than variables; this behavior provides flexibility, but also creates traps for the unwary.
对于那些具有更传统编程语言背景的人来说,这种运行时语法错误的能力可能会令人惊讶,但命令 shell(至少那些在 Bourne 传统中)解析代码的方式有些不同。在许多情况下,shell 参数的行为更像是宏而不是变量;这种行为提供了灵活性,但也为粗心的人设置了陷阱。
Since you tagged this question bash, it's worth noting that there is no word-splitting performed on the result of parameter expansion inside the "new" test syntax available in bash (and ksh/zsh), namely [[
...]]
. So you can also do this:
由于您将此问题标记为bash,因此值得注意的是,在 bash(和 ksh/zsh)中可用的“新”测试语法中,即[[
...没有对参数扩展的结果执行分词]]
。所以你也可以这样做:
if [[ $THEME == '' ]]
The places you can get away without quotes are listed here. But it's a fine habit to always quote parameter expansions anyway except when you explicitly want word-splitting (and even then, look to see if arrays will solve your problem instead).
此处列出了无需引用即可离开的地方。但无论如何总是引用参数扩展是一个很好的习惯,除非你明确想要分词(即使这样,看看数组是否能解决你的问题)。
It would be more idiomatic to use the -z
test operator instead of equality with the empty string:
使用-z
测试运算符而不是与空字符串相等会更惯用:
if [ -z "$THEME" ]
You technically don't need the quotation marks in this simple case; [ -z ]
evaluates to true. But if you have a more complicated expression, the parser will get confused, so it's better to just always use the quotes. Of course, [[
...]]
doesn't require the quotes here, either:
在这种简单的情况下,从技术上讲,您不需要引号;[ -z ]
评估为真。但是如果你有一个更复杂的表达式,解析器会感到困惑,所以最好总是使用引号。当然,[[
...]]
这里也不需要引号:
if [[ -z $THEME ]]
But [[
...]]
is not part of the POSIX standard; for that matter, neither is ==
. So if you care about strict compatibility with other POSIX shells, stick to the quoting solution and use either -z
or a single =
.
但是[[
...]]
不是 POSIX 标准的一部分;就此而言,也不是==
。所以,如果你在意与其他POSIX壳严格的兼容性,坚持引用解决方案,无论是使用-z
或单一=
。
回答by Digital Trauma
[ "$THEME" ]
will evaluate to false if $THEME
is undefined or an empty string and true otherwise. See http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html#Bash-Conditional-Expressions. You can rearrange your if statement to exploit this behavior and have an even simpler conditional:
[ "$THEME" ]
如果$THEME
未定义或为空字符串,则计算结果为 false,否则为 true。请参阅http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html#Bash-Conditional-Expressions。您可以重新排列 if 语句以利用此行为并使用更简单的条件:
if [ "$THEME" ]; then cd 'workspace/aws/ghost/'$THEME'/' grunt watch else echo 'Need to specify theme from the following' ls workspace/aws/ghost fi
"$THEME"
needs to be in double-quotes, in case its value contains whitespace.
"$THEME"
需要用双引号引起来,以防它的值包含空格。
回答by Prem Sriram
Please correct the syntax with the double quotes.
请用双引号更正语法。
if [ "$THEME" == "" ]; then
echo 'Need to specify theme from the following'
ls workspace/aws/ghost
fi