Как насчет того, чтобы просто использовать printf
для преобразования?
printf '^%x\n' 46390 | grep -f- file
(Я не думаю, что преобразование обоих в двоичный формат поможет)
TL,DR :, чтобы воспользоваться преимуществами set -e
, напрямую присвоить результат подстановки команд переменной (, опционально с дополнительными строками вокруг нее ). Не объединяйте несколько подстановок команд вместе и не используйте подстановку команд в аргументе команды.
Проблема не в inherit_errexit
. Это работает. Проблема заключается в ограничениях set -e
(, которые не являются специфическими для bash :другие sh -подобные оболочки имеют ту же проблему ).
Демонстрация :Запустите этот вариант второго примера.
$ cat b2.sh
#!/usr/bin/env bash
set -e
shopt -s inherit_errexit
echo -n $(cat no-such-file; echo >&2 after cat)
echo survived
$./b2.sh
cat: no-such-file: No such file or directory
survived
Обратите внимание, что echo >&2 after cat
не было выполнено. Это было бы, если бы inherit_errexit
был выключен.
Проблема в том, что set -e
останавливает выполнение при ошибке только в простых случаях. Если замена команды возвращает состояние ошибки, это не останавливает выполнение простой команды, содержащей замену. В лучшем случае он может установить статус возврата простой команды, которая, в свою очередь, может остановить выполнение скрипта. «Простая команда» состоит из заданий,перенаправления и необязательное имя исполняемой команды и аргументы. Если перенаправление завершается неудачно, статус возврата равен 1. В противном случае, если имеется имя команды, статус возврата простой команды является статусом возврата исполняемой команды. В противном случае статус возврата является статусом возврата последней подстановки команды или 0, если его нет. Вот несколько примеров простых команд:
true </no/such/file
→ статус 1 из-за неудачного перенаправления false </dev/null
→ статус 1 изfalse
a=b
→ статус 0 из-за отсутствия деталей, которые могут выйти из строя a=$(exit 0) b=$(exit 1) c=$(exit 2)
→ статус 2 от последней подстановки команды a=$(exit 2) b=$(exit 1) c=$(exit 0)
→ статус 0 с момента последней подстановки команды true $(exit 0) $(exit 1) $(exit 2)
→ статус 0 изtrue
Опять же, во всех случаях set -e
остановит сценарий только в том случае, если статус команды не равен нулю. Статус встроенных команд не имеет прямого отношения.
Итак, во втором сценарии echo -n $(…)
имеет статус 0 из echo
(, за исключением случаев, когда echo
не может записать ), независимо от того, что происходит внутри подстановки команды. Поэтому скрипт не остановится на этом, даже если активен set -e
. Аналогично, в третьем скрипте f $(…)
имеет статус 0 из f
.