“-ne”在 bash 中是什么意思?

在 bash 脚本中,命令“-ne”是什么意思?

例如,bash 脚本中的下面一行是做什么的?

[ $RESULT -ne 0 ]
166254 次浏览

"not equal" So in this case, $RESULT is tested to not be equal to zero.

However, the test is done numerically, not alphabetically:

n1 -ne n2     True if the integers n1 and n2 are not algebraically equal.

compared to:

s1 != s2      True if the strings s1 and s2 are not identical.

This is one of those things that can be difficult to search for if you don't already know where to look.

[ is actually a command, not part of the bash shell syntax as you might expect. It happens to be a Bash built-in command, so it's documented in the Bash manual.

There's also an external command that does the same thing; on many systems, it's provided by the GNU Coreutils package.

[ is equivalent to the test command, except that [ requires ] as its last argument, and test does not.

Assuming the bash documentation is installed on your system, if you type info bash and search for 'test' or '[' (the apostrophes are part of the search), you'll find the documentation for the [ command, also known as the test command. If you use man bash instead of info bash, search for ^ *test (the word test at the beginning of a line, following some number of spaces).

Following the reference to "Bash Conditional Expressions" will lead you to the description of -ne, which is the numeric inequality operator ("ne" stands for "not equal). By contrast, != is the string inequality operator.

You can also find bash documentation on the web.

The official definition of the test command is the POSIX standard (to which the bash implementation should conform reasonably well, perhaps with some extensions).

Adding additional context to previous answers.

Since I began programming in BaSH umpteen years ago, I still find the subject of mathematical operators confusing to remember. BaSH is often frustrating to program in, due to its many quirks. A classic example is coding equal/non-equal comparisons of variables containing integers, as it requires a completely different technique as compared with other basic operands (e.g. less than, greater than, etc.). Some typical methods of handling these other operands (e.g. ((..)) ) do not work correctly when applied to equal/non-equal formulas.

Per the OP's question, let's take a look at some examples of how one could attempt to code a numeric comparison of two integers to one another in BaSH, and which methods do or do not work, using examples to help clarify the do's and don'ts. I'll limit my comments to equal/non-equal logic only.

One cannot have a thorough discussion on this topic without mentioning base number systems. BaSH documentation is quite often as clear as mud. For instance, under some circumstances BaSH presumes integers are octal (8-base), while most humans presume decimal (10-base). It's very easy to not realize you're creating a problem while programming a script with number comparisons until you're debugging it at some point in the future due to unexpected results. While BaSH behavior sometimes appears inconsistent, in fact it's simply a matter of fully understanding how BaSH interprets strings and numbers.

Comparing integers without leading zeroes.

When you know for sure your integers to be compared will never have leading zeroes, you could use any of these methods:

#/bin/bash
a=4
b=4
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Comparing integers with leading zeroes.

Now, let's say you will or may have at least one variable with leading zeroes. If this could be the case, then some methods will not work correctly (will generate an error or return wrong result). This happens either because BaSH is interpreting a numeric value as a string and comparing the two numbers as strings, OR because BaSH expects the values to be 8-base integers and encounters a character that it cannot interpret under the octal number system.

There are various ways of working around these problems, but the easiest is to simply not use certain techniques for comparing integers.


These methods don't work when you are attempting to compare actual values. They will incorrectly return a "not equal" result. Of course, if you do in fact wish to compare literal strings, then this might be a desirable outcome, so it really depends on your use case. Either way, the point is these formulas will view "x" vs "0x" as not equal, even though to a human they are the same numeric value.

Take a look at some examples:

Integers, no leading zeroes. Any of these formulas will work.

#!/bin/bash
a=7
b=7
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"


Output:
method 1: equal
method 2: equal
method 3: equal
method 4: equal
method 5: equal

Same here; looks fine (but it's not):

#!/bin/bash
a=7
b=8
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"


Output:
method 1: not equal
method 2: not equal
method 3: not equal
method 4: not equal
method 5: not equal

Problems can begin when leading zeroes are introduced.

#!/bin/bash
a=04
b=4
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"


Output:
method 1: not equal
method 2: not equal
method 3: equal
method 4: equal
method 5: equal

Notice in the example above, the output results are inconsistent. This is because the first two methods are comparing $a vs. $b as strings, meaning their content is compared literally. Meanwhile, the third through fifth methods convert $a and $b to numbers, and then compare them, so those seem to work ok. However, there is another problematic scenario worth mentioning.

The fifth method should generally be avoided.

#!/bin/bash
a=8
b=08
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"


Output:
method 1: not equal
method 2: not equal
method 3: equal
method 4: equal
method 5: main.sh: line 8: ((: 08: value too great for base (error token is "08")
equal

As you can see above, the first two methods return FALSE (not equal) comparison results, because they are comparing the two values as strings. More importantly, the fifth method generates an error, because BaSH is expecting octal numbers and does not know what to do with a non-zero value when it begins with a zero. Another challenge with this method, is even if you were to suppress the error message, it returns a FALSE result every time, regardless of whether or not that is a correct result, as shown below.

#!/bin/bash
a=8
b=09
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"


Output:
method 1: not equal
method 2: not equal
method 3: not equal
method 4: not equal
method 5: main.sh: line 8: ((: 09: value too great for base (error token is "09")
equal

It's also worth mentioning that this variation of the fifth method doesn't work well either:

printf "method 5: "; if (( $a != $b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Nor does this:

printf "method 5: "; if (( "$a" != "$b" )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Bottom Line

The bottom line is when comparing two integers in BaSH, these type of formula expressions are typically what should be used, and not the others mentioned. This presumes your use case involves a desire to compare two 10-base integers to one another using operators of equal or not equal.

printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"

The same logic is true when comparing integers for equality.

printf "method 3: "; if [ $a -eq $b ]; then printf "equal"; else printf "not equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -eq "$b" ]; then printf "equal"; else printf "not equal"; fi; printf "\n"