2012-10-26 3 views
97

У меня есть глубина переменной bash, и я бы хотел проверить, равен ли она 0. Если да, я хочу прекратить выполнение скрипта. До сих пор у меня есть:bash scripting - проверить, равна ли переменная bash 0

zero=0; 

if [ $depth -eq $zero ]; then 
    echo "false"; 
    exit; 
fi 

К сожалению, это приводит к:

[: -eq: unary operator expected 

(может быть немного неточны из-за перевода)

Пожалуйста, как я могу изменить мой сценарий, чтобы получить его за работой?

ответ

88

Похоже, что переменная depth не установлена. Это означает, что выражение [ $depth -eq $zero ] становится [ -eq 0 ] после того, как bash заменяет значения переменных в выражении. Проблема здесь в том, что оператор -eq неправильно используется как оператор с одним аргументом (ноль), но для этого требуются два аргумента. Вот почему вы получаете сообщение об ошибке унарного оператора.

EDIT: Как Doktor J отметил в своем комментарии к этому ответу, безопасный способ избежать проблем с неустановленными переменными в проверках, чтобы вложить переменные в "". См. Его комментарий для объяснения.

if [ "$depth" -eq "0" ]; then 
    echo "false"; 
    exit; 
fi 

незадана переменная используется с командой [ кажется пустым, чтобы колотить. Вы можете проверить это с помощью следующих тестов, которые все оценки для true, потому что xyz либо пусто, либо снята с охраны:

  • if [ -z ] ; then echo "true"; else echo "false"; fi
  • xyz=""; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi
  • unset xyz; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi
+1

Я получаю глубину в результате из другой программы. Я попытался повторить это, и ничего не получилось. Однако, когда я использую [[]], как предложил @Jacek Dominiak, скрипт работает правильно (что довольно странно, если переменная действительно не установлена). Я должен признать, что я действительно не понимаю, что происходит здесь ... – Perlnika

+7

Ваша переменная глубины не установлена. Это означает, что bash видит выражение, которое говорит '[-eq 0]; то ", что не имеет смысла к нему. '[[]]' - это более безопасная версия, которая, кажется, делает bash как [[null -eq 0]], которая является правильной. – cyon

+3

Более безопасный способ проверки заключается в том, чтобы заключить обе стороны в двойные кавычки, то есть 'if [" $ depth "-eq" 0 "]'; таким образом, неустановленная переменная ('$ depth') оценивается как« "(которая, конечно, не равна нулю) –

15

Try:

zero=0; 

if [[ $depth -eq $zero ]]; then 
    echo "false"; 
    exit; 
fi 
+0

Я работал, спасибо! Btw, в чем причина double [[ – Perlnika

+2

Двойные скобки умнее в отношении сохранения unset/null переменных как отдельного слова в выражении. –

+0

@pavel, [встроенный bash, см. Https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins –

41

Двойной esis ((...)) используется для арифметических операций.

Двойные квадратные скобки [[ ... ]] могут быть использованы для сравнения и изучения числа (только целые поддерживаются), со следующими операторами:

· NUM1 -eq NUM2 returns true if NUM1 and NUM2 are numerically equal. 

· NUM1 -ne NUM2 returns true if NUM1 and NUM2 are not numerically equal. 

· NUM1 -gt NUM2 returns true if NUM1 is greater than NUM2. 

· NUM1 -ge NUM2 returns true if NUM1 is greater than or equal to NUM2. 

· NUM1 -lt NUM2 returns true if NUM1 is less than NUM2. 

· NUM1 -le NUM2 returns true if NUM1 is less than or equal to NUM2. 

Например

if [[ $age > 21 ]] # bad, > is a string comparison operator 

if [ $age > 21 ] # bad, > is a redirection operator 

if [[ $age -gt 21 ]] # okay, but fails if $age is not numeric 

if (($age > 21)) # best, $ on age is optional 
+3

Можете ли вы привести некоторые аргументы/доказательство того, почему некоторые подходы являются хорошими, а другие - плохими? – Dennis

+0

@Dennis: [This] (http://tldp.org/LDP/abs/html/comparison-ops.html), кажется, проверяет утверждения в ответе (-> разные скобки для сравнения строк и целых чисел) – mozzbozz

+0

'best, $ on age не является обязательным. Он не работает без' $ ' –

2

Вы можете попробовать это:

: ${depth?"Error Message"} ## when your depth variable is not even declared or is unset. 

ПРИМЕЧАНИЕ: Здесь всего ? после depth.

или

: ${depth:?"Error Message"} ## when your depth variable is declared but is null like: "depth=". 

ПРИМЕЧАНИЕ: Вот это :? после depth.

Здесь, если найдена переменная depthnull, она распечатает сообщение об ошибке, а затем выйдет.

1

В частности: ((depth)). Например, следующие отпечатки 1.

declare -i x=0 
((x)) && echo $x 

x=1 
((x)) && echo $x 
6

вы также можете использовать этот формат и использовать операторы сравнения, как «==» «< =»

if (($total == 0)); then 
     echo "No results for ${1}" 
     return 
    fi