shell脚本中的=
,==和
-eq
有什么区别?
以下两者有什么区别吗?
[ $a = $b ]
[ $a == $b ]
[ $a -eq $b ]
仅仅是 =
和 ==
仅在变量包含数字时才使用吗?
这取决于操作符周围的测试结构。您可以选择双括号、双括号、单括号或< code>test。
如果您使用((
…))
,您正在使用==
测试算术相等性,就像在C中一样:
$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1
(注意:0
在 Unix 意义上表示 true
,失败的测试会导致非零数字。
在双括号内使用-eq
是语法错误。
如果您使用[
…]
[或单括号)或
…
]](或双括号)或
测试-eq
、-ne-gt
或
$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0
单括号或双括号内的
==
(或test
命令)是字符串比较运算符之一:
$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1
作为字符串运算符,
=
等效于 ==
。另外,请注意 =
或 ==
周围的空格:这是必需的。
虽然你可以做 [
[ 1 =
= 1 ]] 或 [[ $((1 1 )) == 2 ]],
但它测试的是字符串相等性——而不是算术相等性。
因此< code>-eq
可能会产生预期的结果,即< code>1 1的整数值等于< code>2,即使右边是一个字符串并有一个尾随空格:
$ [[ $(( 1+1 )) -eq "2 " ]]; echo $?
0
而相同的字符串比较会获取尾随空间,因此字符串比较失败:
$ [[ $(( 1+1 )) == "2 " ]]; echo $?
1
一个错误的字符串比较会产生一个完全错误的答案。< code>10在字典上小于< code>2,因此字符串比较返回< code>true或< code>0。很多人都被这种错误所困扰:
$ [[ 10 < 2 ]]; echo $?
0
< code>10在算术上小于< code>2的正确测试是:
$ [[ 10 -lt 2 ]]; echo $?
1
在注释中,有一个关于对字符串使用整数 -eq
对不相同的字符串返回 true 的技术原因的问题:
$ [[ "yes" -eq "no" ]]; echo $?
0
原因是Bash是非类型化的。< code>-eq使字符串被解释为整数(如果可能的话),包括基本转换:
$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0
和0
如果Bash认为它只是一个字符串:
$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1
所以[[“yes”-eq“no”]]
等同于[[0-eq 0]]<-code>
最后一点:测试构造的许多Bash特定扩展不是POSIX,因此在其他shell中可能会失败。其他shell通常不支持
[[…]]
和((…))
或==
。
=
和==
用于字符串比较-eq
用于数字比较-eq
与-lt
、-le
、-gt
、-ge
和-ne
在同一个家族中
==
特定于bash(sh(Bourne shell)中不存在,…)。为了兼容性,首选使用POSIX=
。在bash中,两者是等效的,在sh=
中是唯一有效的。
$ a=foo
$ [ "$a" = foo ]; echo "$?" # POSIX sh
0
$ [ "$a" == foo ]; echo "$?" # bash-specific
0
$ [ "$a" -eq foo ]; echo "$?" # wrong
-bash: [: foo: integer expression expected
2
(注意:确保引用变量扩展。不要省略上面的双引号。)
如果您正在编写#! /bin/bash
脚本,那么我建议改用[[
。双方括号[[…]]
形式具有更多功能,更自然的语法,更少的陷阱会绊倒您。例如,$a
周围不再需要双引号:
$ [[ $a == foo ]]; echo "$?" # bash-specific
0
另请参见:
1. Shell 运算符概述 1.1 Shell 运算符是什么 与其他语言一样,Shell 也有运算符,在 Shell 中其根据类型不同也有不少运算符分类,那么什么是运算符呢?例如大家都知道在算术运算中的加减乘除,+ 就是我们 Shell 中的算术运算符的一种,当然还有很多其他的功能各异的运算符,作为条件判断与算术操作等重要功能,构成了 Shell 中的基本元素。 1.2 为什么要用运算符 当我们
这是C++程序员常见的错误,包括熟练的C++程序员也会把相等(==)与赋值(=)运算符相 混淆。这种错误的破坏性在于它们通常不会导致语法错误,而是能够顺利编译,程序运行完后,因为运行时的逻辑错误而得到错误结果。 C++有两个方面会导致这些问题。一个是任何产生数值的表达式都可以用于任何控制结构的判断部分。如果数值为0,则当作false,如果数值为非0,则当作true。第二是C++赋值会产生一个值,
本节介绍简单的 C++ if 结构,使程序根据某些条件的真假做出判断。如果条件符合,即为真(true),则执行if结构体的语句;如果不符合,即条件为假(false),则不执行语句,稍后将举例说明。 if结构中的条件可以用相等运算符(equality operator)和关系运算符(relational operator)表示,如图1.13关系运算符具有相同的优先级,结合律为从左向右。相等运算符
Shell支持的运算符: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 一、算数运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。 expr 是一款表达式计算工具,使用它能完成表达式的求值操作。 例如,两个数相加(注意使用的是反引号 ` 而不是单引号 ‘): #!/bin/bash val=`expr
问题内容: 为什么最后一个语句无法编译为错误:,并且有一种方法可以修改结构或扩展运算符以对嵌套数组(或字典)执行相等性检查? 问题答案: 更新: 条件一致性已在 Swift 4.1中 实现 。 特别是: 现在,标准库类型Optional,Array和Dictionary的元素类型符合Equatable时,它们便符合Equatable协议。… (来自Swift CHANGELOG)。 现在可以任意嵌
赋值运算符 变量赋值,初始化或改变一个变量的值。 = 等号=赋值运算符,既可用于算术赋值,也可用于字符串赋值。 var=27 category=minerals # "="左右不允许有空格 注意,不要混淆=赋值运算符与=测试操作符。 # = 作为测试操作符 if [ "$string1" = "$string2" ] then command fi # [ "X$string1"