`set -e` та` grep` ідіома для запобігання передчасного виходу зі скрипту оболонки, коли шаблон не знайдено


15

Потрібна допомога - у контексті сценаріїв оболонок на базі GNU / LINUX:

Я завжди користуюся set -e. Часто мені хотілося б grepі не завжди хочеться, щоб сценарій припиняв виконання, якщо grepстатус виходу із 1зазначенням шаблону не знайдено.

Щось я намагався вирішити цю проблему:

(Спробуйте я)
Якщо set +o pipefailі попросити grep з чимось на кшталт, grep 'p' | wc -lя отримаю бажану поведінку, доки майбутній супровідник не дозволить pipefail. Крім того, мені подобається включити, pipefailщоб це не працювало для мене.

(Спробуйте II)
Використовуйте sedабо awkі тільки лінії друку, що відповідають шаблону, а потім wcвідповідні лінії для перевірки відповідності шаблону. Мені не подобається цей варіант , тому що використання sedдля grepвиглядає як обхідний шлях для моєї справжньої проблеми.

(Спробуйте III)
Цей мій найменший улюблений - щось на зразок:set +e; grep 'p'; set-e

Будь-яке розуміння / ідіоми було б дуже вдячним - дякую.

Відповіді:


19

Ви можете поставити grep в ifумові, або якщо вам не байдуже стан виходу, додайте || true.

Приклад: grepвбиває оболонку

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

рішення 1: викинути ненульовий статус виходу

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

рішення 2: явно перевірити стан виходу

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

З сторінки "bash man", яка обговорює set -e:

Оболонка не виходить, якщо команда, яка не вдається, є частиною списку команд, що знаходиться відразу через деякий час або до появи ключового слова, частина тесту, що слідкує за застереженими словами if або elif , частиною будь-якої команди, виконаної в && або ││ списку, крім команда після остаточного && або ││ , будь-яка команда в конвеєрі, але остання, або якщо зворотне значення команди інвертується ! .


З огляду на те, що bash тривалий час не реалізовувався -е правильно, можливо, документація ще не є коректною. Оскільки текст здається тотожним man-сторінці bash-3.x, будь ласка, зверніть увагу: всі версії bash до того, як bash4.0 реалізував -e неправильно.
schily

Також зауважте, що як стандарт POSIX також був невірним, ми змінили текст POSIX для обробки помилок з -e в 2009 році
schily

1
@schily Будь ласка, дайте вказівники, де можна дізнатись, що таке «правильна» поведінка -e, що bash <4 зробив інакше, а що було змінено в POSIX.
zwol

makeПомилки в bash-3 в основному роблять його непридатним для використання, оскільки він не завжди виходив з помилок. Для відповідних дискусій POSIX ви можете перевірити austingroupbugs.net
schily

@schily Не могли б ви бути більш конкретними?
zwol
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.