Проверьте, является ли одно число равным другому числу в bash

Я пытался сравнить, равны ли два числа в 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 3!"
    fi
}
fun2

Соответствующие ошибки отображаются ниже строк, вызвавших эти ошибки.

Ответ 1

Это должно быть:

 if [ $x -eq 3 ]; then .....

объяснение:

Чтобы сравнить целые числа, вы должны использовать эти операторы (скопированные из 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

Операторы == и! = предназначены только для сравнения строк.

для информации: "[" команда является псевдонимом для команды "test".

Ответ 2

Для первого сообщения об ошибке удалите знак доллара $ и не допускается пробел вокруг знака равенства =

x=3

Для второго сообщения об ошибке вставьте пробел и знак доллара $ до x и пробел после 3

if [ $x -eq 3 ]

Как правильно указал @lentar, это должно быть -eq и ни = ни ==.

Ответ 3

Shell scripting на самом деле не был полным языком, и он сильно зависит от работы других внешних команд.

Переменные используют сигилу, которая составляет $ перед ними. Многие языки сценариев оболочки используют переменные сигилы, чтобы различать строку и переменную.

Например:

foo=foo_value
echo foo foo $foo foo

Будет печать:

foo foo foo_value foo

Обратите внимание, что кавычки не нужны для выражения echo для строк. Пакет Windows Batch очень похож:

set foo = foo_value
echo foo foo %foo% foo

Как вы можете видеть, сигил используется, когда переменная предположительно расширяется, но не тогда, когда вы ее определяете. Это потому, что оболочки Unix являются интеллектуальными оболочками. Они запускают командную строку, прежде чем она будет выполнена. Оболочка заменит переменные среды перед выполнением:

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

Это напечатает:

The value of foo is foo
The value of bar is whose value is this

Если вы используете команду set -xv, вы увидите, что $foo="whose value is this" разворачивается до bar=whose value is this" до его выполнения.

В оболочках Bourne, таких как Kornshell и BASH, утверждение 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

Обратите внимание, что предложение if не является логическим выражением. Это действительная команда, которая выполняется.

Где-то в начале разработки Unix была создана test команда. Вы можете сделать мужской тест и посмотреть, как его использовать.

Команда 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

Если вы это сделаете:

$ ls -li /bin/test /bin/[

Вы увидите, что команда под названием [ самом деле существует и является жесткой ссылкой на 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

Точно такой же скрипт, как и выше, но с [ вместо test.

Это объясняет, почему вам нужно тире во многих тестах (это параметр для команды test, а параметры начинаются с тире!). Это также объясняет, почему вам нужны пробелы вокруг [ и ]. Это настоящие команды Unix, а команды Unix должны иметь пробелы вокруг них, поэтому оболочка может их обрабатывать.

Еще одна проблема заключается в том, почему оболочка имеет два разных набора тестов для строк и чисел. Это потому, что строки могут содержать только цифры, но не являются числовыми. Например, если вы делаете инвентарь, у вас может быть номер детали 001 и 01. Численно они равны, но, как строки, это две разные строки. Сценарий оболочки не знает. Вместо этого вы должны сообщить сценарию оболочки, если это числовое сравнение или сравнение строк.

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

Вы можете попробовать несколько других вещей:

$ echo "*"    #Echos the asterisk
$ echo *      #No quotes: Prints all files in current directory

Обратите внимание, что оболочка расширяет * перед выполнением команды echo. Это основное различие между сценарием оболочки и типичным языком программирования. Сначала оболочка расширяет (заполняет переменные среды, подстановку глобусов, подкоды запуска), прежде чем она действительно выполнит команду.

set -xv покажет вам, какая команда выполняется, и как оболочка расширяет команду перед выполнением. Выполнение set +xv отключит это. Поиграйте с этим, и вы скоро поймете оболочку немного лучше.

Ответ 4

  • пробелы являются обязательными в выражении [ ], поэтому

    if [ $x == 3 ]; then

  • вам нужно сигила по переменным в тестах [ ]