bash -e выходит, если let или expr оценивается до 0

У меня есть скрипт bash, который устанавливает -e, поэтому скрипт выйдет из любого статуса выхода! = 0.

Я пытаюсь выполнить некоторую базовую арифметику оболочки, назначенную для переменных, а иногда выражение равно 0, что приводит к тому, что статус выхода команды let или expr будет «1».

Вот пример:

#!/bin/bash -ex echo "Test 1" Z=`expr 1 - 1` || true echo "Z will print" let "A=4 - 4" echo "A WILL NEVER PRINT $A" Y=`expr 1 - 1` echo "Y WILL NEVER PRINT $Y" X=$(expr 2 - 2) echo "X WILL NEVER PRINT $X" 

Выход:

 $ ./test_error.sh + echo 'Test 1' Test 1 ++ expr 1 - 1 + Z=0 + true + echo 'Z will print' Z will print + let 'A=4 - 4' 

Мой вопрос заключается в том, что такое идиоматический сценарий bash, позволяющий сценарию терпеть неудачу при реальных ошибках выхода, а не в базовой арифметике, равной 0. Я мог бы суффикс всех этих выражений с помощью:

 A=`expr $C - $D` || true 

Но это кажется взломанным.

3 Solutions collect form web for “bash -e выходит, если let или expr оценивается до 0”

Не используйте expr для арифметики. Это уже давно устарело: оболочки теперь имеют арифметику, с конструкцией $((…)) (POSIX) или с let builtin (ksh / bash / zsh) или конструкцией ((…)) (ksh / bash / ЗШ).

let и ((…)) return 1 (код состояния сбоя), если последнее оцениваемое выражение равно 0. Чтобы избежать этого, чтобы ваш скрипт вышел из set -e , уделите последнее выражение не возвратом 0, например:

 let "a = 2 - 2" 1 ((a = 2 - 2, 1)) 

В качестве альтернативы используйте || true || true идиома:

 ((a = 2 - 2)) || true 

В качестве альтернативы, сделайте свою арифметику внутри $((…)) и ваших заданий вне. Назначение возвращает статус последней подстановки команды в значении или 0, если нет подстановки команды, поэтому вы в безопасности. Это имеет дополнительное преимущество для работы в любой оболочке POSIX (например, тире).

 a=$((2 - 2)) 

Используйте $(( $C - $D )) вместо вашего арифметического. Это более эффективно.

У меня была та же проблема . ТЛ; др:

Если последний ARG [of let] имеет значение 0, пусть возвращает 1; пусть возвращает 0 в противном случае.

  • Как ограничить время работы программы в Linux?
  • Как я могу печатать только переменные, определенные внутри моего сценария оболочки?
  • Как определить последнюю версию в URL?
  • синтаксическая ошибка возле неожиданного токена `do
  • Как запустить несколько файлов конфигурации через скрипт?
  • Возможно ли создать среду Linux без традиционной командной оболочки?
  • Как реализовать циклический поток данных между взаимосвязанными командами?
  • Выход Bash из подкоманды
  • Как закрыть сервер netcat через n секунд
  • Объединить несколько строк с пробелами в них?
  • Выполнение программы в соответствии с последней измененной датой
  • Как получить уровень громкости из командной строки?
  • Interesting Posts

    Как я могу найти утечку памяти в текущем процессе?

    Как сжать корневую файловую систему без загрузки livecd

    Создание символической ссылки с двоеточием в имени на cygwin bash

    Может ли btrfs обрабатывать разные уровни RAID для разных подвыборов?

    Как собирать случайные фрагменты файла tar?

    Скрипт, чтобы определить, являются ли файлы изображениями

    Как использовать agetty из командной строки

    Могу ли я масштабировать дисплей ноутбука HiDPI, оставив внешний дисплей без изменений?

    запускать команды внутри awk перед печатью

    если я использую мультипликативные суффиксы в systemd, то ошибки – «не удалось проанализировать значение ресурса»

    Где я могу найти журналы Openbox?

    Как сохранить временные данные

    Получение информации из sysfs

    Найти шаблон между специальными символами

    Копировать Vim в системный буфер обмена, не перезаписывая регистр по умолчанию (")

    Linux и Unix - лучшая ОС в мире.