检查一个数字是否等于 bash 中的另一个数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15867813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check whether one number equals another number in bash
提问by Anderson Green
I've been trying to compare whether two numbers in Bash are equal (and print a message if they are equal), but I'm getting some strange error messages for this simple program:
我一直在尝试比较 Bash 中的两个数字是否相等(如果相等则打印一条消息),但是对于这个简单的程序,我收到了一些奇怪的错误消息:
#!/bin/bash
fun2 (){
$x = 3
//#prog.sh: line 4: =: command not found
if [x == 3]
then
//#prog.sh: line 6: [x: command not found
echo "It's 3!"
fi
}
fun2
The corresponding errors are shown below the lines that caused those errors.
相应的错误显示在导致这些错误的行下方。
回答by loentar
It must be:
肯定是:
if [ $x -eq 3 ]; then .....
if you prefer a more readable and self-explanatory code, use this syntax:
如果您更喜欢更易读和不言自明的代码,请使用以下语法:
if test $x -eq 3; then .....
explanation:
解释:
To compare integers you must use those operators (copied from man test):
要比较整数,您必须使用这些运算符(从 man test 复制):
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
operators == and != are for string comparison only.
运算符 == 和 != 仅用于字符串比较。
for information: "[" command is an alias for system "test" command.
信息:“[”命令是系统“test”命令的别名。
回答by David W.
Shell scripting wasn't really meant to be a full language, and it is heavily dependent upon other external commands to work.
Shell 脚本并不真正意味着成为一种完整的语言,它在很大程度上依赖于其他外部命令才能工作。
Variables use a sigilwhich is that $
in front of them. A lot of shell scripting languages use variable sigils to help distinguish between a string and a variable.
变量使用印记这是$
摆在他们面前。许多 shell 脚本语言使用变量符号来帮助区分字符串和变量。
For example:
例如:
foo=foo_value
echo foo foo $foo foo
Will print:
将打印:
foo foo foo_value foo
Note that quotes are not necessary for the echostatement for strings. Windows Batch shell is very similar:
请注意,字符串的echo语句不需要引号。Windows Batch shell 非常相似:
set foo = foo_value
echo foo foo %foo% foo
As you can see, the sigilis used when the variable is suppose to be expanded, but not when you define it. That's because Unix shells are intelligent shells. They munge the command line before it is even executed. The shell will substitute the environment variables beforeexecution:
正如你所看到的,印记当变量是假设扩展使用,而不是当你定义它。那是因为 Unix shell 是智能 shell。他们甚至在执行之前就修改了命令行。shell 会在执行前替换环境变量:
foo=bar
$foo="whose value is this" #Note the dollar sign!
echo The value of foo is $foo
echo The value of bar is $bar
This will print out:
这将打印出:
The value of foo is foo
The value of bar is whose value is this
If you use the set -xv
command, you'll see that $foo="whose value is this"
is expanded to bar=whose value is this"
before it is executed.
如果您使用该set -xv
命令,您会看到它在执行之前$foo="whose value is this"
被扩展为bar=whose value is this"
。
In Bourne style shells like Kornshell and BASH, the if
statement isn't what you think it is. The if
command executes the statement, and will select the if clauseif that command returns a zero value. For example:
在像 Kornshell 和 BASH 这样的 Bourne 风格的 shell 中,if
语句并不是你想象的那样。该if
命令执行语句,如果该命令返回零值,则将选择if 子句。例如:
cat "foo" > my_file #Create a one line file with the string foo in it.
if grep -q "foo" my_file #grep command will return a zero exit code if it finds foo
then
echo "The string 'foo' is in file my_file"
fi
Notice that the if clauseisn't a boolean statement. It's an actual command that is executed.
请注意,if 子句不是布尔语句。这是一个实际执行的命令。
Somewhere early in Unix development, the test
command was created. You can do a man testand see how to use it.
在 Unix 开发早期的某个地方,test
创建了该命令。你可以做一个人测试,看看如何使用它。
The test
command allows you to do this:
该test
命令允许您执行以下操作:
foo=3
bar=3
if test foo -eq bar
then
echo "foo and bar are equal"
else
echo "foo and bar are not equal"
fi
If you do this:
如果你这样做:
$ ls -li /bin/test /bin/[
You will see that a command called [
actually exists, and is a hard link to the test
command. This was created to make an if
statement look more like a if statement you'll see in regular programming languages:
您将看到一个名为的命令[
实际上存在,并且是该test
命令的硬链接。创建它是为了使if
语句看起来更像您将在常规编程语言中看到的 if 语句:
foo=3
bar=3
if [ foo -eq bar ]
then
echo "foo and bar are equal"
else
echo "foo and bar are not equal"
fi
Exact same script as above, but with [
instead of test
.
与上面完全相同的脚本,但使用[
而不是test
.
This explains why you need the dashin many tests (it's a parameter to the test
command, and parameters start with a dash!). It also explains why you need spaces around the [
and ]
. These are actual Unix commands, and Unix commands must have white spaces around them, so the shell can process them.
这解释了为什么在许多测试中需要破折号(它是test
命令的参数,参数以破折号开头!)。它还解释了为什么在[
和周围需要空格]
。这些是实际的 Unix 命令,Unix 命令周围必须有空格,以便 shell 可以处理它们。
Another issues is why does shell have two different sets of tests for strings and numbers. That's because strings may contain nothing but digits, but are not really numeric. For example, if you do inventory, you might have a part number 001
and 01
. Numerically, they're equal, but as strings, they're two different strings. There is no way for the shell script to know. Instead, you must let the shell script know if it's a numeric comparison or a string comparison.
另一个问题是为什么 shell 对字符串和数字有两组不同的测试。那是因为字符串可能只包含数字,但不是真正的数字。例如,如果您进行库存,您可能有一个零件号001
和01
。在数字上,它们是相等的,但作为字符串,它们是两个不同的字符串。shell 脚本无法知道。相反,您必须让 shell 脚本知道它是数字比较还是字符串比较。
Perl has similar issues since you don't declare variables as numeric or non-numeric:
Perl 有类似的问题,因为您没有将变量声明为数字或非数字:
Shell Script Perl
Boolean Operator Numeric String Numeric String
=================== ======= ====== ======= ======
Equals -eq = == eq
Not Equals -ne != != ne
Greater Than -gt > > gt
Less Than -lt < < lt
Greater or Equals -ge >= >= ge
Less Than or Equals -le <= <= le
You can try a few other things:
您可以尝试其他一些事情:
$ echo "*" #Echos the asterisk
$ echo * #No quotes: Prints all files in current directory
Notice again the shell expandsthe *
before executing the echocommand. This is the main difference between a shell script and a typical programming language. The shell first does expansion (fill in environment variables, glob substitution, run sub-commands) before it actually execute the command.
再次注意 shell在执行echo命令之前扩展了。这是 shell 脚本和典型编程语言之间的主要区别。在实际执行命令之前,shell 首先进行扩展(填充环境变量、全局替换、运行子命令)。*
The set -xv
will show you what command is being executed, and how the shell expandsthe command before executing. Doing set +xv
will shut that off. Play around with that, and you'll soon understand the shell a bit better.
该set -xv
会告诉你正在执行什么命令,以及shell如何扩大执行前的命令。这样做set +xv
会关闭它。试试这个,你很快就会更好地理解 shell。
回答by Olaf Dietsche
For the first error message, remove the dollar sign $
and no spaces are allowed around the equal sign =
对于第一条错误信息,去掉美元符号$
,等号周围不允许有空格=
x=3
For the second error message, insert a space and a dollar sign $
before x
and a space after 3
对于第二错误消息,插入一个空格和一个美元符号$
之前x
和之后的空间3
if [ $x -eq 3 ]
As @loentar correctly pointed out, it must be -eq
and neither =
nor ==
.
正如@loentar 正确指出的那样,它必须是-eq
,既不是=
也不是==
。