Linux shell if less

Shell: Does «a -lt b» not mean true if a is less than b?

I’m not trained in Linux, but I can muddle through with some doc lookups, but I’m stumped. I found a script that helps set the date on my dd wrt router when it starts up, but only if the current date is less than the stored date. I can share the whole script if you want, but it boils down to this statement not evaluating to true when I expect it to. I’m putting the literals in, rather than the variables, and it still does not return true, it executes the «else» statement:

 if [ 021715402012 -lt 021815402012 ] then echo "the first seems less than the second" else echo "the first does not seem less than the second for some reason" fi 

I would expect «the first seems less than the second» but this is not the case. Is it an overflow problem? I tried to make it a string compare like this:

if [ x021715402012 -lt x021815402012 ] 
if [ "x021715402012" -lt "x021815402012" ] 

it always executes the else. Does » a -lt b » not mean true if a is less than b? Any insight into this would be appreciated, I’m stumped!

Hmm it prints «the first seems less than the second» for me when i test your example. What bash or sh version is this? If you want more information about -lt etc you can check help test , help [ or man test .

Also works fine on my openwrt router. But I clearly have a different implementation that you do, because mine gives «bad number» with the x included.

4 Answers 4

The mnemonics such as -lt might be said to come from the original Fortran comparators such as .LT. from the late 1950s.

Yes, in the shell, -lt does a ‘less than’ numeric comparison. (Be aware, though, that in Perl, the numeric comparisons are < etc, and the string comparisons are denoted by the alphabetic operators such as -lt !)

Читайте также:  Wallpaper engine analog linux

However, in some, perhaps many, shells the conversion and comparison may well be done in the local long integer format. If you’re on a 32-bit machine, the values you quote exceed the 32-bit (signed) range by a factor of 10 or so. On a 64-bit machine, or with a shell that uses long long , you’d be OK.

The hex equivalents of the decimal numbers are 021715402012 = 0x50E56BD1C and 021815402012 = 0x5144C9E1C; they can’t be octal because of the 8. (However, if the shell does interpret the leading zero as ‘octal’, then the second number is just 021 or 17 decimal because the 8 ends the octal number. However, the 64-bit shells I tested on (Mac OS X 10.7.3 and RHEL 5) both seemed to treat them as decimal, not octal.)

The example code below, compiled under 64-bit gives the following output:

021715402012 = 240565532 = 0x050E56BD1C 021815402012 = 340565532 = 0x05144C9E1C 

Compiled under 32-bit, it gives the following output:

021715402012 = 2147483647 = 0x007FFFFFFF 021815402012 = 2147483647 = 0x007FFFFFFF 

If this was what happened in your shell, then the resulting behaviour of -lt would be explained. You could confirm it by testing whether the two values are -eq ; counter-intuitively, this would probably evaluate to true under the hypothesis that you are using a 32-bit shell that limits its arithmetic to long (32-bit) signed integers.

#include #include int main(void) < char *array[] = < "021715402012", "021815402012" >; for (int i = 0; i < 2; i++) < int j = atoi(array[i]); long k = strtol(array[i], 0, 10); printf("%-10s = %10d = 0x%.10lX\n", array[i], j, k); >return 0; > 

Источник

Linux shell if less

if [ «$a» -eq «$b» ]

if [ «$a» -ne «$b» ]

if [ «$a» -gt «$b» ]

if [ «$a» -ge «$b» ]

if [ «$a» -lt «$b» ]

if [ «$a» -le «$b» ]

меньше или равно (внутри двойных круглых скобок)

больше (внутри двойных круглых скобок)

больше или равно (внутри двойных круглых скобок)

[[ $a == z* ]] # истина, если $a начинается с символа "z" (сравнение по шаблону) [[ $a == "z*" ]] # истина, если $a равна z* [ $a == z* ] # имеют место подстановка имен файлов и разбиение на слова [ "$a" == "z*" ] # истина, если $a равна z* # Спасибо S.C.

меньше, в смысле величины ASCII-кодов

Читайте также:  Linux посмотреть пароль samba

больше, в смысле величины ASCII-кодов

Обратите внимание! Символ «>» необходимо экранировать внутри [ ].

См. Пример 25-6 относительно применения этого оператора сравнения.

строка «пустая» , т.е. имеет нулевую длину

Пример 7-5. Операции сравнения

#!/bin/bash a=4 b=5 # Здесь переменные "a" и "b" могут быть как целыми числами, так и строками. # Здесь наблюдается некоторое размывание границ #+ между целочисленными и строковыми переменными, #+ поскольку переменные в Bash не имеют типов. # Bash выполняет целочисленные операции над теми переменными, #+ которые содержат только цифры # Будьте внимательны! echo if [ "$a" -ne "$b" ] then echo "$a не равно $b" echo "(целочисленное сравнение)" fi echo if [ "$a" != "$b" ] then echo "$a не равно $b." echo "(сравнение строк)" # "4" != "5" # ASCII 52 != ASCII 53 fi # Оба варианта, "-ne" и "!=", работают правильно. echo exit 0

Пример 7-6. Проверка — является ли строка пустой

#!/bin/bash # str-test.sh: Проверка пустых строк и строк, не заключенных в кавычки, # Используется конструкция if [ . ] # Если строка не инициализирована, то она не имеет никакого определенного значения. # Такое состояние называется "null" (пустая) (это не то же самое, что ноль). if [ -n $string1 ] # $string1 не была объявлена или инициализирована. then echo "Строка \"string1\" не пустая." else echo "Строка \"string1\" пустая." fi # Неверный результат. # Выводится сообщение о том, что $string1 не пустая, #+не смотря на то, что она не была инициализирована. echo # Попробуем еще раз. if [ -n "$string1" ] # На этот раз, переменная $string1 заключена в кавычки. then echo "Строка \"string1\" не пустая." else echo "Строка \"string1\" пустая." fi # Внутри квадратных скобок заключайте строки в кавычки! echo if [ $string1 ] # Опустим оператор -n. then echo "Строка \"string1\" не пустая." else echo "Строка \"string1\" пустая." fi # Все работает прекрасно. # Квадратные скобки -- [ ], без посторонней помощи определяют, что строка пустая. # Тем не менее, хорошим тоном считается заключать строки в кавычки ("$string1"). # # Как указывает Stephane Chazelas, # if [ $string 1 ] один аргумент "]" # if [ "$string 1" ] два аргумента, пустая "$string1" и "]" echo string1=initialized if [ $string1 ] # Опять, попробуем строку без ничего. then echo "Строка \"string1\" не пустая." else echo "Строка \"string1\" пустая." fi # И снова получим верный результат. # И опять-таки, лучше поместить строку в кавычки ("$string1"), поскольку. string1="a = b" if [ $string1 ] # И снова, попробуем строку без ничего.. then echo "Строка \"string1\" не пустая." else echo "Строка \"string1\" пустая." fi # Строка без кавычек дает неверный результат! exit 0 # Спвсибо Florian Wisser, за предупреждение.

Пример 7-7. zmost

#!/bin/bash #Просмотр gz-файлов с помощью утилиты 'most' NOARGS=65 NOTFOUND=66 NOTGZIP=67 if [ $# -eq 0 ] # то же, что и: if [ -z "$1" ] # $1 должен существовать, но может быть пустым: zmost "" arg2 arg3 then echo "Порядок использования: `basename $0` filename" >&2 # Сообщение об ошибке на stderr. exit $NOARGS # Код возврата 65 (код ошибки). fi filename=$1 if [ ! -f "$filename" ] # Кавычки необходимы на тот случай, если имя файла содержит пробелы. then echo "Файл $filename не найден!" >&2 # Сообщение об ошибке на stderr. exit $NOTFOUND fi if [ $ != "gz" ] # Квадратные скобки нужны для выполнения подстановки значения переменной then echo "Файл $1 не является gz-файлом!" exit $NOTGZIP fi zcat $1 | most # Используется утилита 'most' (очень похожа на 'less'). # Последние версии 'most' могут просматривать сжатые файлы. # Можно вставить 'more' или 'less', если пожелаете. exit $? # Сценарий возвращает код возврата, полученный по конвейеру. # На самом деле команда "exit $?" не является обязательной, # так как работа скрипта завершится здесь в любом случае,

построение сложных условий проверки

Читайте также:  Добавить маршрут умолчанию linux

exp1 -a exp2 возвращает true, если оба выражения, и exp1, и exp2 истинны.

exp1 -o exp2 возвращает true, если хотябы одно из выражений, exp1 или exp2 истинно.

Примечания

Как указывает S.C., даже заключение строки в кавычки, при построении сложных условий проверки, может оказаться недостаточным. [ -n «$string» -o «$a» = «$b» ] в некоторых версиях Bash такая проверка может вызвать сообщение об ошибке, если строка $string пустая. Безопаснее, в смысле отказоустойчивости, было бы добавить какой-либо символ к, возможно пустой, строке: [ «x$string» != x -o «x$a» = «x$b» ] (символ «x» не учитывается).

Источник

Оцените статью
Adblock
detector