amarao (amarao_san) wrote,
amarao
amarao_san

Categories:

unix way

Идея: утилита делает одну вещь, но делает её хорошо.

Что значит "хорошо"? Что нам не надо прикладывать специальных усилий для борьбы с этой вещью ради того, что она делает. Утрируя: мне нужно запаковать файл, я делаю |gzip, а выходе имею запакованный файл. Утилита чуть-чуть присыпана опциями по вкусу, но сама идея от этого не меняется - на входе данные, на выходе архив.

С учётом, что паковка - математическая операция (чистая), ошибки от gzip мы можем получить только если у нас в системе что-то плохо (ENOMEM), либо что-то плохо "до/после" в пайпе. И нас это полностью устраивает, потому что gzip в режиме паковки не может генерировать ошибок, ассоциированных с входными данными. Мы можем смело полагать, что gzip нам не добавит сложности в обработке ошибок - ошибка либо системная (фатальная), либо на входе/выходе. Если мы считаем вход/выход тоже системными (cat, редирект), то ошибки становятся системными все. Нам достаточно увидеть ненулевой код возврата, чтобы знать, что "была системная ошибка и операция не удалась". Более того, за вычетом мелкого нюанса с ENOSPACE (где-то дальше по пайпу), мы можем считать, что операция транзакционная - либо сработало и запаковало, либо нет. То есть gzip в режиме паковки нам не добавляет головной боли. Берёшь и используешь. Идеальная утилита.

А теперь смотрим на распаковку. Что должен делать gzip при фигне на входе? "not in gzip format", errno = 1, " Operation not permitted". Эта ошибка крайне отличается от enomem, либо ошибок чтения/записи из/в stdin/out. У нас появляется ошибка пользовательских данных. На одной и той же машине в тех же самых условиях с одним файлом всё отработает, а с другим нет.

Получается, что у нас есть два разных типа ошибок, которые мы должны обработать: системные ошибки (ENOMEM, broken pipe), и ошибки обработки данных (not in gzip format).

Мы можем начать играться с set -o pipefail, но мы всё равно не можем обработать эту ошибку отдельно. Мы получаем в пайпа код 1, и даже не знаем, кто его выставил без чтения stderr.

Получается, что у нас инструмент может генерировать два класса ошибок: ошибки среды исполнения и ошибки пользовательских данных, но мы не можем их различать.

Опытный админ знает мерзкий хак:

set -o pipefail
cat /proc/cpuinfo |sort|(gzip -d || exit 33) |sort|wc -l
echo $?
33

Мы не можем различить ошибку пользовательских данных от системной ошибки, но мы уже можем узнать, что именно gzip нам испортил жизнь, а не кто-то вокруг.

Если мы хотим иметь разное поведение для системной ошибки и пользовательских данных, то инструмент 'bash pipe' уже не работает. Более того, к gzip, внезапно, вопросы, потому что он возвращает 1 на системные ошибки и на ошибки пользовательского ввода.

И возникает вопрос: можно ли считать unix-way'ным использование gzip -d? Делает ли он "одну вещь, но делает её хорошо"?
Tags: философия администрирования
Subscribe

  • Ненависть

    [ 6706.680875] megaraid_sas 0000:03:00.0: 5844 (529754980s/0x0020/DEAD) - Fatal firmware error: Line 977 in ../../dm/src/dm.c [ 6706.682102]…

  • megacli

    Вы мне все скажете спасибо (кто поймёт и почувствует). megacli -LDPDInfo -a0|egrep '(Inq|Virtual)'

  • Теоретическая задача перезагрузки железки

    Задача крайне любопытная - если SAS-HBA повис, можно ли его (её?) перезагрузить? Тривиальные методы с sg_reset не проходят - всё IO зависает, так…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 6 comments