完整答案

完整答案

我尝试使用这个:

$ if [$a == 1] then { echo 'yes'; } fi;

但我收到错误:

-bash: syntax error near unexpected token `}'

正确的格式是什么?我尝试了几个但没有运气。

答案1

[根据 bash 的说法,只是另一个字符;它不是自我界定的。所以你需要在[和周围添加空格]。尽管你最好使用[[]]

并且后面的命令if(是的,是一个命令)必须以或 换行符[终止。;

最后,==(不是 posix,FWIW;posix 更喜欢=)是字符串相等,而不是数字相等。

所以你的意思可能是:

if [[ $a -eq 1 ]]; then echo yes; fi

但你可以使用算术评估来代替:

if ((a == 1)); then echo yes; fi

(在算术求值中,相等性是==,并且您不需要$在变量名之前。我知道这很令人困惑。)

欲了解更多信息[help test。关于[[:帮助[[(基于test)。关于((help let。关于bashman bash

答案2

概括

使用:

if [ "$a" = 1 ]; then echo yes; fi

完整答案

bash报错:-bash:意外标记“}”附近出现语法错误是试图引导代码编写者发现错误,但 bash 很容易出错,并在错误的地方发出错误信号。

实际上,代码中有几个错误。但让我们用更简单的代码行重现 bash 报告的错误:

$ if true then { true; } fi;
bash: syntax error near unexpected token `}'

如果该行稍有变化,则会在大约相同的位置报告错误,但略有不同:

$ if true then true; fi;
bash: syntax error near unexpected token `fi'

并且,这还报错:

$ if true; then; true; fi;
bash: syntax error near unexpected token `;'

所有这一切的发生是因为所需的语法(从手册中复制)是:

if list; then list; fi;

其中list是一个或多个以 a 结尾的简单命令(或管道或复合命令)新队或一个分号。请注意,一般来说,换行符可以替换为分号,反之亦然。

这是有效的(没有报告语法错误)

if   true;   then   true;   fi

这也是有效的:

if     true
then   true
fi

或者:

if echo start; true; then echo decision; true; echo next; fi;

或者换行符和/或分号的其他变体。

当然,最后一个分号不是必需的,但也不是禁止的。

此外,[]要求(通常)空格被 bash 区分为单词(标记),因此被理解为测试

if [ $a == 1 ]; then { echo 'yes'; } fi;       # still subtly incorrect.

但是,变量扩展也应该用引号括起来("$a"),==在 bash 中有效,但在其他一些 shell 中可能无效,所以我们应该使用=内部 single [ ]'yes'技术上不需要引用(即使它没有害处),并且{ }单个简单命令不需要大括号,所有这些都使它成为一个更好的版本:

if [ "$a" = 1 ]; then echo yes; fi

或者,如果您选择使用 bash/ksh/zsh [[ ]]

if [[ $a == 1 ]]; then echo yes; fi

=最后,使用or进行的测试==是字符串比较,而不是数字比较,+1因此不是1即使它们的价值相同。要进行数值测试,您可以使用-eq.

答案3

[是 Bash 中的一个命令,就像任何其他命令一样,例如ifwhile等。如果您仔细检查手册页,您可以看到这一点:

$ man [
NAME
       bash, :, ., [, alias, bg, bind, break, builtin, caller, cd, command, .....

您还可以通过以下示例判断这是一个真正的命令:

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

第一个结果是[Bash 的内置版本。第二个是[GNU coreutils 中包含的版本。

在 Fedora 上,您可以看到它属于哪个 RPM:

$ rpm -qf /usr/bin/[
coreutils-8.5-7.fc14.x86_64

鉴于此,您需要确保所有命令周围都有空格,以便正确解析它们。

这样做:

$ if [$a == 1] ...

与此相同:

$ lsblah
bash: lsblah: command not found...

ls命令无法正确解析,因为它没有使用空格缓冲以便可以解析。

答案4

if [ "$a" = 1 ]; then echo yes; fi

或者

if test "$a" -eq 1 ; then echo yes; fi

或者

if /usr/bin/test "$a" -eq 1;then echo yes;fi

shell 将剪切命令行以在分号处进行测试(然后将参数添加到测试的命令行 - argc/argv 如果它不是内置的)

但这不起作用:

if test "$a"-eq 1; then echo yes; fi

shell 应该在哪里分割要测试的参数?所以它不会分割字符串 '+1-eq 1'

如果这样做,该测试是一个单独的程序就变得显而易见:

 sh:~$ LANG=C sh -c 'a=+1 ; if test "$a"-eq 1 ; then echo yes ; fi'
 sh: 1: test: +1-eq: unexpected operator

与此相比:

 sh:~$ LANG=C sh -c 'a=+1 ; if /usr/bin/test "$a"-eq 1;then echo yes;fi'
 /usr/bin/test: missing argument after '1'

嗯,要测试的相同参数有不同的错误消息......

相关内容