我尝试使用这个:
$ 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
。关于bash
:man 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 中的一个命令,就像任何其他命令一样,例如if
、while
等。如果您仔细检查手册页,您可以看到这一点:
$ 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'
嗯,要测试的相同参数有不同的错误消息......