shell 为什么我得到一个'unary operator expected'错误?

vbopmzt1  于 2023-05-29  发布在  Shell
关注(0)|答案(3)|浏览(763)

我正在编写一个shell脚本来简化我的开发工作流程。
它接受一个参数,说明我将在哪个主题文件夹中工作,并在该目录上启动grunt watch
如果我在没有必要参数的情况下调用脚本,我当前会打印一个警告,提示需要将主题指定为命令行参数。
我想打印可用选项的列表,例如。主题目录
这就是我目前所知道的……

THEME=$1

if [ $THEME == '' ]
then
    echo 'Need to specify theme'
else
    cd 'workspace/aws/ghost/'$THEME'/'
    grunt watch
fi

理想情况下,我将echo行的输出替换为themes父目录的ls,如下所示

THEME=$1

if [ $THEME == '' ]
then
    echo 'Need to specify theme from the following'
    ls workspace/aws/ghost
else
    cd 'workspace/aws/ghost/'$THEME'/'
    grunt watch
fi

然而,这给了我以下错误

./ghost_dev.sh: line 3: [: ==: unary operator expected
l3zydbqr

l3zydbqr1#

您需要在$THEME周围加上引号:

if [ $THEME == '' ]

否则,当你没有指定主题时,$THEME会扩展为nothing,shell会看到以下语法错误:

if [ == '' ]

加上引号,像这样:

if [ "$THEME" == '' ]

空的$THEME的展开产生以下有效比较:

if [ "" == '' ]

这种运行时语法错误的能力可能会让那些具有更传统编程语言背景的人感到惊讶,但命令shell(至少是Bourne传统中的命令shell)解析代码的方式有些不同。在许多上下文中, shell 参数的行为更像宏而不是变量;这种行为提供了灵活性,但也为粗心者制造了陷阱。
由于您将这个问题标记为bash,因此值得注意的是,在bash(和ksh/zsh)中可用的“新”测试语法(即[[... ]]。所以你也可以这样做:

if [[ $THEME == '' ]]

这里列出了你可以不带引号地离开的地方。但是,无论如何,总是引用参数扩展是一个好习惯,除非您明确希望进行单词拆分(即使这样,也要看看数组是否可以解决您的问题)。
使用-z测试操作符而不是空字符串的相等操作符会更符合习惯:

if [ -z "$THEME" ]

当然,[[... ]]也不需要任何引号:

if [[ -z $THEME ]]

但是[[... ]]不是POSIX标准的一部分;因此,==也不是。因此,如果您关心与其他POSIX shell的严格兼容性,请坚持引用解决方案并使用-z或单个=

w6lpcovy

w6lpcovy2#

如果$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"需要用双引号括起来,以防它的值包含空格。

wixjitnu

wixjitnu3#

请用双引号更正语法。

if [ "$THEME" == "" ]; then
     echo 'Need to specify theme from the following'
     ls workspace/aws/ghost
 fi

相关问题