Команда expr в Linux: руководство и шпаргалка
Быстрая навигация
- Команда expr
- Операторы expr
- Арифметика с expr
- Сравнение выражений
- Длина строки
- Сравнение и поиск префикса
- Инкремент и декремент переменной
- Извлечение подстроки
- Использование в shell-скриптах
- Альтернативы и рекомендации
Краткое резюме
- expr вычисляет выражения и печатает результат. Поддерживает целочисленную арифметику, сравнения и некоторые строковые операции.
- Удобен в простых скриптах и ад-хок задачах, когда не хочется подключать bc или awk.
- Требует пробелов между токенами и экранирования специальных символов в shell.
Важно: expr работает с целыми числами. Для вещественной арифметики используйте bc или awk.
Что такое expr
expr — это утилита командной строки, реализующая простую вычислительную и строковую логику в соответствии с POSIX. Она принимает выражение в аргументах, оценивает его и выводит результат в stdout. expr полезен для быстрого выполнения задач без подключения сложных языков обработки текста.
Ключевые свойства:
- Работает в интерактивном терминале и в скриптах shell.
- Ожидает, что каждый токен (число, оператор, строка) отделён пробелом.
- Возвращает числовой результат или длину/совпадения строк.
- Возвращаемые коды выхода: 0 при успешном вычислении (обычно), 1 если выражение ложно при логическом использовании, 2 при ошибке.
Синтаксис:
expr expressionПример базового вида:
expr arg1 operator arg2Аргументы могут быть числами или строками, в зависимости от оператора. Операторы бывают арифметические, реляционные, строковые и логические.
Опции и справка
expr не имеет множества флагов как современные утилиты. Тем не менее, у неё есть стандартные акции помощи:
expr --helpи
expr --version
Первая команда покажет синтаксис и краткое описание. Вторая — номер версии и информацию об авторстве и лицензии.
Операторы expr — краткая шпаргалка
Арифметические:
- сложение
- вычитание
- * умножение (в shell нужно экранировать или брать в кавычки)
- / целочисленное деление
- % остаток от деления
Сравнения и логика:
- = равенство строк
- <, > порядок для целых (экранируйте в shell)
- != неравенство (экранируйте в shell)
- : сопоставление префикса/регулярного выражения — возвращает длину совпадения
Строковые функции:
- length string — длина строки
- substr string pos len — подстрока, позиция начинается с 1
Примечание: токены должны быть разделены пробелами. Например, для умножения используйте экранирование: *.
Выполнение арифметики с expr
Простой пример суммы:
expr 15 + 12Остальные операции:
expr 15 - 12
expr 15 \* 5
expr 10 / 2Если вы не хотите экранировать символы, можно обернуть оператор или аргументы в одинарные кавычки:
expr '5' '*' '3'Или использовать подстановку команд в современном стиле:
result=$(expr 8 + 7)
echo $result
Почему нужно экранировать? Shell может интерпретировать символы как шаблоны (globbing) или перенаправление. Например, “*” подставит имена файлов в текущей директории, если его не экранировать.
Пример — целочисленное деление и остаток
expr 17 / 3 # → 5
expr 17 % 3 # → 2Важно помнить, что expr работает с целыми числами. Десятичные дроби будут отброшены при делении.
Сравнение выражений
expr можно использовать для логических проверок. В большинстве случаев команда вернёт “1” если условие истинно и “0” если ложно. Однако в скриптах полезнее ориентироваться на код возврата.
Примеры:
expr 40 = 50
expr 40 \< 50
expr 45 \!= 55Экранируйте символы <, >, != через обратный слэш или заключайте в кавычки. Если условие истинно, вывод будет 1 (и код выхода обычно 0), при ложном — 0 (код выхода 1).
Длина строки
Функция length возвращает количество символов в строке, включая пробелы:
expr length 'How To Geek'Вывод: 11 (9 символов + 2 пробела).
Если нужно игнорировать пробелы, удалите их заранее, например через tr:
expr length "$(echo 'How To Geek' | tr -d ' ')"Результат будет 9.
Сопоставление и поиск общего префикса
Оператор “:” возвращает длину совпадающего префикса между двумя строками или длину совпадения по регулярному выражению.
Примеры:
expr 'HowToGeek' : 'HowTo'
# вывод: 5
expr 'How To Geek' : 'How To Geek'
# вывод: 11
expr 'How To Geek' : 'Linux'
# вывод: 0Оператор полезен, когда нужно узнать, насколько две строки совпадают в начале.
Инкремент и декремент переменной
В скриптах часто нужно увеличить или уменьшить значение счётчика. С expr это делается так:
a=20
# инкремент
a=$(expr $a + 1)
echo $a
# декремент
a=20
a=$(expr $a - 1)
echo $aСовременный стиль shell предпочитает арифметику через (( )):
a=20
((a++))
echo $a(( )) быстрее и не требует запуска внешней программы. Используйте expr когда совместимость POSIX важна или когда вы обрабатываете строки вместе с выражением.
Извлечение подстроки
Функция substr возвращает подстроку, позиция начинается с 1:
a=HowToGeek
b=$(expr substr $a 2 5)
echo $b
# вывод: owToG (символы со 2 по 6)Учтите, что если позиция выходит за пределы строки, результат будет пустой строкой.
Использование expr в shell-скриптах
Простой сценарий для сложения двух чисел:
echo 'Enter two numbers'
read a
read b
sum=$(expr $a + $b)
echo 'Sum of two numbers is=' $sumСделайте файл исполняемым и запустите:
chmod +x my_script.sh
./my_script.sh
Советы по безопасности ввода
- Проверяйте, что введённые значения действительно числа. Иначе expr может выдавать ошибки или неожидаемые результаты.
Пример простого валидатора чисел:
re='^-?[0-9]+$'
if ! [[ $a =~ $re ]]; then
echo 'Первый аргумент не целое число'
exit 1
fiИспользуйте такое проверяющее условие перед передачей значений в expr.
Альтернативы и когда не использовать expr
expr хорош для простых случаев, но у него есть ограничения:
- Поддерживает только целые числа.
- Запускает внешний процесс для каждого вызова (производительность).
- Синтаксис чувствителен к пробелам и экранированию.
Альтернативы:
- let и встроенные арифметические выражения в bash:
let 'x = 5 * 3'
((x = 5 * 3))(( )) — предпочитаемый способ в bash для арифметики и инкремента/декремента.
bc — для десятичных дробей и сложных вычислений:
echo "scale=4; 5 / 3" | bc- awk — мощный текстовый процессор с поддержкой чисел с плавающей точкой и регулярных выражений:
awk 'BEGIN {print 5/3}'- cut/sed — для извлечения подстрок и манипуляции текстом, если нужно больше гибкости.
Когда expr подходит:
- Нужна простая целая арифметика в POSIX-скрипте.
- Требуется быстрое определение длины строки или префикса.
Когда expr не подходит:
- Нужны дробные числа.
- Есть высокие требования к производительности.
- Регулярные выражения сложнее префикса — используйте grep/sed/awk.
Практические примеры и шаблоны
Шаблон: безопасное сложение двух вводимых чисел
#!/bin/sh
printf 'Введите два целых числа:\n'
read a
read b
re='^-?[0-9]+$'
if ! echo "$a" | grep -Eq "$re" || ! echo "$b" | grep -Eq "$re"; then
printf 'Ошибка: введите целые числа\n' >&2
exit 2
fi
sum=$(expr $a + $b)
printf 'Сумма: %s\n' "$sum"Тест-кейсы для проверки корректности:
- Ввод 2 и 3 → вывод 5
- Ввод -1 и 1 → вывод 0
- Ввод нецифрового символа → код выхода 2 и сообщение об ошибке
Паттерны использования и эвристики
- Если считаете выражение простым (++, –, +, -), используйте (( )) в bash для скорости.
- Если скрипт должен быть максимально портируемым на /bin/sh, expr остаётся хорошим выбором.
- Для строковых манипуляций с регулярными выражениями применяйте awk или sed.
Ментальная модель: представьте expr как «микро-калькулятор и простой парсер строк», но не как полноценный язык программирования.
Рекомендации по миграции и совместимости
- Если ваш скрипт выполняется в dash или другом минимальном sh, expr скорее всего доступен. Тем не менее проверьте поведение на целевой системе.
- При переносе на bash можно заменить частые вызовы expr на встроенные арифметические выражения (( )) для ускорения.
- Если нужны десятичные вычисления, мигрируйте на bc или awk.
Риск-матрица и смягчения
- Неправильный ввод → ошибка выполнения или неожиданный вывод. Смягчение: валидация ввода.
- Проблемы с локалью и кодировкой при подсчёте символов (UTF-8 vs byte-oriented) → expr оперирует байтами, а не обязательно символами Unicode. Смягчение: используйте wc -m или awk с поддержкой мультибайтных символов для подсчёта реальных символов.
Быстрая шпаргалка (cheat sheet)
- expr 3 + 4 → 7
- expr 6 * 7 → 42
- expr 10 / 3 → 3
- expr 10 % 3 → 1
- expr length ‘строка’ → длина в байтах
- expr substr ‘строка’ 2 3 → подстрока
- expr ‘abc’ : ‘ab’ → 2
Контрпримеры и когда expr даёт неверные ожидания
- Работа с UTF-8: expr length ‘я’ может вернуть 2 или 3 в зависимости от байтовой длины символа в текущей локали. Для подсчёта реальных символов используйте:
echo -n 'я' | wc -m- Дробные числа: expr 5 / 2 → 2 (не 2.5). Для дробей применяйте bc.
Роли и чеклисты
Для разработчика:
- Проверить, нужны ли дроби — если да, заменить expr на bc/awk.
- Убедиться, что выражения экранированы от shell-глоббинга.
Для системного администратора:
- Убедиться, что /usr/bin/expr присутствует на целевых хостах.
- Проверить поведение в минимальных шеллах (dash, ash).
Для инженера по безопасности:
- Валидация внешнего ввода до передачи в expr.
- Минимизировать использование внешних программ при обработке чувствительных данных.
Пример миграции на более современный стиль
Исходный код на expr:
a=10
b=$(expr $a + 5)
echo $bЭквивалент на bash:
a=10
((a += 5))
echo $aКраткие рекомендации по отладке
- Если expr выдаёт ошибку, проверьте пробелы между токенами.
- Если видите пустой вывод, попробуйте обернуть аргументы в кавычки, чтобы проверить, не произошло ли разбиение или подмена.
- Для диагностики включайте set -x в скрипт, чтобы видеть, что именно передаётся в expr.
Сводка и выводы
expr остаётся полезным инструментом для простых целочисленных вычислений и базовых строковых операций в POSIX-совместимых скриптах. Для современных bash-скриптов стоит предпочесть встроенную арифметику (( )) и более мощные инструменты (bc, awk) там, где требуется точность, скорость или поддержка Unicode.
Важно: проверяйте ввод и учитывайте ограничения по кодировке при работе со строками.
Ключевые шаги к практическому использованию:
- Решите, нужна ли совместимость POSIX или преимущества bash.
- Валидация ввода перед передачей в expr.
- Экранирование специальных символов или использование кавычек.
- Тестирование на целевой системе и проверка кодов возврата.
Критерии приёмки
- Скрипт корректно вычисляет положительные и отрицательные целые числа.
- Скрипт корректно обрабатывает некорректный ввод и возвращает понятное сообщение об ошибке.
- Все символы шаблонов и операторы корректно экранированы и не подставляют файлы.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента