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 

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

  • почему существует случайное поведение для фоновой работы?
  • Как сравнить дубликаты файлов в одном каталоге и объединить их вместе
  • Предотвращение расширения параметра несколько раз
  • Выход Bash из подкоманды
  • `Unhandled Exception: System.ArgumentNullException: значение не может быть ошибкой null.` при запуске` dotnet run` с использованием сценария запуска
  • передача команд sftp в sftp соединение в файле
  • Какой язык сценариев или платформа использовать для загрузки веб-страниц и взаимодействия с экраном?
  • Какова цель запуска сценария?
  • 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 в противном случае.

    Interesting Posts

    Установить уровень запуска при загрузке через аппаратный (аналоговый) вход, переключатель и т. Д.?

    Установите новый файловый менеджер по умолчанию для firefox в Archlinux

    Использование точки с запятой для отделения фонового задания от следующего?

    rsync: исключая шаблон в файле exclude, не работает

    Добавить bash в базовое ядро ​​Linux?

    Как включить Iptables в Fedora 18?

    Ошибки файловой системы при восстановлении многих файлов

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

    копировать рекурсивно, кроме скрытого каталога

    Синхронизация времени синхронизации RTC с временем Linux при запуске

    PuTTY не подключается через SSH; другие клиенты работают нормально

    Не удается ssh из Интернета, но может с localhost

    Автоматические фоновые процессы

    «Не удалось подключиться к дисплею»: ошибка 0.0 "на Cygwin

    Объявить новый ключ-модификатор с помощью XKB

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