Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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
Bash 为什么我会得到一个';应为一元运算符';错误?_Bash_Shell - Fatal编程技术网

Bash 为什么我会得到一个';应为一元运算符';错误?

Bash 为什么我会得到一个';应为一元运算符';错误?,bash,shell,Bash,Shell,我正在编写一个shell脚本来简化我的开发工作流程 它需要一个参数来确定我将在哪个主题文件夹中工作,并在该目录上启动grunt watch 如果在没有必要参数的情况下调用脚本,则当前正在打印一条警告,提示需要将主题指定为命令行参数 我想打印一个可用选项的列表,例如主题目录 这就是我目前所拥有的 THEME=$1 if [ $THEME == '' ] then echo 'Need to specify theme' else cd 'workspace/aws/ghost/'

我正在编写一个shell脚本来简化我的开发工作流程

它需要一个参数来确定我将在哪个主题文件夹中工作,并在该目录上启动
grunt watch

如果在没有必要参数的情况下调用脚本,则当前正在打印一条警告,提示需要将主题指定为命令行参数

我想打印一个可用选项的列表,例如主题目录

这就是我目前所拥有的

THEME=$1

if [ $THEME == '' ]
then
    echo 'Need to specify theme'
else
    cd 'workspace/aws/ghost/'$THEME'/'
    grunt watch
fi
理想情况下,我会将
echo
行的输出替换为主题父目录的
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

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

if [ $THEME == '' ]
否则,当您不指定主题时,
$theme
将展开为空,shell将看到以下语法错误:

if [ == '' ]
添加了引号,如下所示:

if [ "$THEME" == '' ]
扩展空的
$THEME
会生成此有效比较:

if [ "" == '' ]
运行时语法错误的这种能力对于那些背景是更传统的编程语言的人来说是令人惊讶的,但是命令shell(至少是Bourne传统中的那些)解析代码的方式有些不同。在许多情况下,shell参数的行为更像宏而不是变量;这种行为提供了灵活性,但也为粗心的人制造了陷阱

由于您标记了这个问题bash,因此值得注意的是,在bash(和ksh/zsh)中可用的“新”测试语法中,没有对参数扩展的结果执行分词,即
[[
]
。所以你也可以这样做:

if [[ $THEME == '' ]]
下面列出了不带引号就可以离开的地方。但不管怎样,总是引用参数展开式是一个好习惯,除非您明确希望分词(即使这样,也要看看数组是否能解决您的问题)

如果使用
-z
测试运算符而不是与空字符串相等,则更为惯用:

if [ -z "$THEME" ]
在这个简单的例子中,技术上不需要引号<代码>[-z]计算结果为true。但是,如果您有一个更复杂的表达式,解析器会感到困惑,因此最好总是使用引号。当然,
[[
..
]
此处也不需要任何代码:

if [[ -z $THEME ]]

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

请使用双引号更正语法

 if [ "$THEME" == "" ]; then
     echo 'Need to specify theme from the following'
     ls workspace/aws/ghost
 fi
[“$THEME”]
如果
$THEME
未定义或为空字符串,则计算结果为false,否则为true。看见您可以重新排列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”];然后 cd“workspace/aws/ghost/”$THEME/” 咕噜手表 其他的 echo“需要从以下内容中指定主题” ls工作区/aws/ghost fi
“$THEME”
需要用双引号引起来,以防其值包含空格。

好的,我已经在变量赋值周围添加了引号,使用了[[]语法,并在“$THEME”上添加了引号,以获得最佳实践。真是一种享受!谢谢。作业的工作方式有点不同;至少RHS上不会出现分词,所以我认为
THEME=“$1”
THEME=$1
是相同的,尽管我很想纠正一下我忘记的角落大小写。@chepner-你说得对,作业右侧的扩展不需要引号。当然,仍然需要引用任何文本空白。您应该使用
-z
检查空变量:
如果[-z“$THEME”]
。编辑标题,我将尝试使用
-z
如果[-z”$THEME”]]
非常有效-谢谢。提示:将自动告诉您,
$THEME
周围需要双引号。请更正if语句的语法。有两个错误。当“then”与“if”在同一行时,必须使用分号。或者在下一行写上“then”。以及随附的“如果”也缺失。请在发布之前测试您的答案。想象一下,当一个初学者在尝试你的答案时。他会收到一些错误信息。我整理了答案。