Сравнение целых чисел в Bash
Я пытаюсь написать Bash-скрипт, который проверяет, есть ли хотя бы один параметр, и если он есть, то является ли этот параметр 0 или 1.
Вот мой скрипт:
#/bin/bash
if (("$#" < 1)) && ( (("$0" != 1)) || (("$0" -ne 0q)) ); then
echo this script requires a 1 or 0 as first parameter.
fi
xinput set-prop 12 "Device Enabled" $0
Однако, скрипт выдает следующие ошибки:
./setTouchpadEnabled: line 2: ((: ./setTouchpadEnabled != 1: syntax error: operand expected (error token is "./setTouchpadEnabled != 1")
./setTouchpadEnabled: line 2: ((: ./setTouchpadEnabled -ne 0q: syntax error: operand expected (error token is "./setTouchpadEnabled -ne 0q")
Что я делаю не так?
3 ответ(ов)
Вот более простой способ решения вашей задачи в стиле ответа на StackOverflow:
#/bin/bash
if [[ ${1:-2} -ge 2 ]]; then
echo "Первый параметр должен быть 0 или 1"
fi
# Остальная часть скрипта...
Вывод
$ ./test
Первый параметр должен быть 0 или 1
$ ./test 0
$ ./test 1
$ ./test 4
Первый параметр должен быть 0 или 1
$ ./test 2
Первый параметр должен быть 0 или 1
Объяснение
[[ ]]
- используется для более гибкой оценки условий.${1:-2}
- расширение параметров, которое дает значение2
, если первый параметр не задан.-ge 2
- проверяет, больше или равно ли значение второго параметра двум (2
).
Таким образом, если пользователь не передает ни одного аргумента или передает значение больше или равное двум, скрипт уведомит о том, что первый параметр должен быть 0 или 1.
В нулевом параметре командной строки содержится самa команда (или иногда сама оболочка). Вам следует использовать переменную $1
для доступа к первому аргументу.
Ваше логическое выражение также немного запутано:
(("$#" < 1)) && ( (("$1" != 1)) || (("$1" -ne 0q)) )
Это выражение говорит, что если количество аргументов меньше одного, тогда первый аргумент не может быть равен 1 или 0, что явно нелогично. Если количество аргументов меньше одного, то аргумент $1
вообще не существует.
Вероятно, вы хотите написать что-то вроде этого:
(( "$#" )) && (( $1 == 1 || $1 == 0 )) # Если это выражение истинно, значит, передан хотя бы один аргумент, и его значение равно 0 или 1.
В данной конструкции сначала проверяется, что число аргументов больше нуля, а затем проверяется, равен ли первый аргумент 0 или 1. Это более логично и работает корректно.
Этот вопрос уже обсуждался, но решил поделиться своим вариантом, так как считаю, что команда case
— это недооценённый инструмент. (Может, потому что люди думают, что она медленнее, но на самом деле она как минимум так же быстра, а иногда и быстрее, чем if
.)
Вот пример использования:
case "$1" in
0|1) xinput set-prop 12 "Device Enabled" $1 ;;
*) echo "Этот скрипт требует 1 или 0 в качестве первого параметра." ;;
esac
В этом коде проверяется, является ли первый аргумент скрипта (доступный через $1
) равным 0 или 1. Если условие истинно, выполняется команда xinput
для включения или отключения устройства. В противном случае выводится сообщение об ошибке.
В Bash как проверить, начинается ли строка с определённого значения?
Как изменить цвет вывода echo в Linux
Почему сравнение строк с помощью '==' и 'is' иногда дает разные результаты?
Как работает "cat << EOF" в bash?
Как разделить большой текстовый файл на меньшие файлы с равным количеством строк?