Насколько стабильны оболочки Unix «API-интерфейсы stdin / stdout»?

grepping, awking, sedding и piping – повседневная рутина пользователя любой Unix-подобной операционной системы, может быть, она находится в командной строке или внутри скрипта оболочки (в дальнейшем называются фильтрами ).

По сути, при работе со стандартными программами Unix CLI и встроенными оболочками (теперь называются командами ) фильтры нуждаются в точном ожидаемом формате для stdin, stdout и stderr на каждом шаге фильтра для правильной работы. Я называю этот точный ожидаемый формат некоторой команды API этой команды в следующем.

Как кто-то с фоном веб-разработки, я сравниваю этот вид сбора данных и обработки данных технически с помощью веб-скрепок – техника, которая очень нестабильна, когда есть небольшое изменение в представлении данных.

Теперь мой вопрос касается стабильности API-интерфейсов Unix.

  1. Выполняют ли команды в Unix-подобных операционных системах официальную стандартизацию в отношении их ввода и вывода?
  2. Были ли в истории случаи, когда обновление какой-либо важной команды приводило к нарушению функциональности какого-либо фильтра, который был создан с использованием старой версии указанной команды?
  3. Имеют ли команды Unix со временем созревание, что абсолютно невозможно изменить таким образом, чтобы какой-то фильтр мог сломаться?
  4. В случае, если фильтры могут время от времени ломаться из-за изменения командных API, как я могу как разработчик защитить свои фильтры от этой проблемы?

  • Настройка рабочей среды - Konsole или другой терминал - открытие нескольких вкладок и запуск некоторых команд
  • Могу ли я читать и записывать альтернативные файловые виджеты HFS + или потоки данных NTFS из Linux?
  • Использовать случай предоставления файлового API для терминала / консоли
  • API ядра файловой системы
  • Реализация Cocoa API для Linux?
  • «Sh», запущенный с помощью execl (), становится зомби
  • В системах Unix, почему мы должны явно открывать файлы `open ()` и `close ()`, чтобы они могли читать `read ()` или `write ()` them?
  • стоп трубы () открытие stdin
  • 6 Solutions collect form web for “Насколько стабильны оболочки Unix «API-интерфейсы stdin / stdout»?”

    В стандарте POSIX 2008 есть раздел, описывающий «Shell and Utilities» . Как правило, если вы придерживаетесь того, что ваши сценарии должны быть достаточно перспективными, за исключением, возможно, для устареваний, но это вряд ли произойдет за одну ночь, поэтому у вас должно быть достаточно времени для обновления ваших сценариев.

    В некоторых случаях, когда формат вывода для одной утилиты широко варьируется в разных платформах и версиях, стандарт POSIX может включать в себя опцию, обычно называемую -p или -P которая определяет гарантированный и предсказуемый формат вывода. Примером этого является утилита time , которая имеет широко различающиеся реализации. Если вам нужен стабильный формат API / вывода, вы будете использовать time -p .

    Если вам нужно использовать утилиту фильтра, которая не покрыта стандартом POSIX, то вы в значительной степени находитесь на пути к разработчикам пакетов распространения / вверх по течению, так же, как вы находитесь во власти удаленных веб-разработчиков при выполнении веб-скрепок.

    Я попытаюсь ответить из своего опыта.

    1. Команды действительно не соответствуют формальной спецификации, но они соблюдают требование потреблять и генерировать текст, ориентированный на линию.

    2. Да, конечно. До того, как утилиты GNU стали стандартом де-факто, многие производители имели бы причудливый выход, особенно в отношении ps и ls . Это вызвало много боли. Сегодня только HP предлагает сверхпривычные команды. Исторически сложилось так, что утилиты Berkeley Software Distribution (BSD) были серьезным перерывом в прошлом. Спецификация POSIX была перерывом с прошлым, но теперь она широко принята.

    3. Команды Unix действительно созрели с течением времени. По-прежнему невозможно разбить какой-то скрипт, написанный для более старой версии. Подумайте о недавней тенденции к UTF-8 в качестве кодирования текстового файла. Это изменение потребовало изменения основных утилит, таких как tr . В прошлом простой текст был почти всегда ASCII (или что-то близкое), поэтому прописные буквы составляли числовой диапазон, как и строчные буквы. Это больше не относится к UTF-8, поэтому tr получает возможность принимать различные параметры командной строки, чтобы указать такие вещи, как «верхний регистр» или «буквенно-цифровой».

    4. Один из лучших способов «пробить» ваши фильтры – не зависеть от конкретного макета текста. Например, не делайте cut -c10-24 , что зависит от положения строки. cut -f2 этого используйте cut -f2 , который cut -f2 поле с разделителем табуляции. awk разбивает любую входную строку на $ 1, $ 2, $ 3 … которые по умолчанию разделены пробелами. В зависимости от концепций более высокого уровня, таких как «поля», а не концепций более низкого уровня, таких как позиция столбца. Кроме того, используйте регулярные выражения: sed и awk могут делать вещи с регулярными выражениями, которые не заботятся о некоторой дисперсии ввода. Другой трюк состоит в том, чтобы обработать вход в нечто, формат которого может быть разборчивым. Используйте tr -cs '[a-zA-z0-9]' '[\n]' чтобы разбить текст на одно слово в строке без знаков препинания. Вам просто все равно, как выглядит исходный текст в этом случае.

    Во-первых, очень короткие ответы на ваши вопросы:

    1. Формальная стандартизация соглашений ввода / вывода: нет
    2. Поломка в прошлом из-за изменения выпуска: да
    3. Абсолютно невозможно сломать будущие фильтры: нет
    4. Как я могу защитить себя от изменений: быть консервативным

    Когда вы говорите «API», вы используете термин, который (для хорошего или плохого) подразумевает слишком большую формальность вокруг соглашений ввода / вывода фильтров. Очень (и я имею в виду «очень») в целом, основные соглашения для данных, которые можно легко фильтровать,

    • каждая строка ввода является полной записью
    • в каждой записи поля разделяются известным символом разделителя

    Классическим примером будет формат / etc / passwd. Но эти соглашения по умолчанию, вероятно, в какой-то степени нарушаются, чем к письму.

    • Существует множество фильтров (часто написанных на awk или perl), которые обрабатывают многострочные форматы ввода.
    • Существует множество шаблонов ввода (например, / var / log / messages), где нет четко определенной структуры поля, и должны использоваться более общие методы на основе регулярных выражений.

    Ваш четвертый вопрос, как защитить себя от изменений в структуре вывода, действительно единственный, о котором вы можете что-либо сделать.

    • Как сказал @ jw013 , посмотрите, что говорят стандарты posix. Конечно, posix не определяет все команды, которые вы хотите использовать в качестве исходных источников.
    • Если вы хотите, чтобы ваши сценарии были переносимыми, постарайтесь избегать идиосинкразий любой версии какой-либо команды, которой вы случайно не являетесь. Например, во многих версиях стандартных Unix-команд GNU есть нестандартные расширения. Они могут быть полезны, но вы должны избегать их, если хотите максимальную мобильность.
    • Попытайтесь узнать, какие подмножества аргументов команд и форматы вывода имеют тенденцию быть стабильными на разных платформах. К сожалению, для этого требуется доступ к нескольким платформам вместе со временем, поскольку эти различия не будут записываться нигде, даже неофициально.

    В конце концов, вы не можете полностью защитить себя от проблем, о которых вы беспокоитесь, и нет единого места для поиска «окончательного» утверждения о том, что должна выполнить определенная команда. Для многих сценариев оболочки, особенно написанных для личного или маломасштабного использования, это просто не проблема

    Только охватывая 1) вашего вопроса.

    Естественно, API-интерфейсы могут всегда меняться по желанию своих создателей и, соответственно, разрывать зависимое программное обеспечение на любом языке. Тем не менее, отличная идея API-интерфейсов ввода-вывода Unix «заключается в том, что практически нет (может быть, 0x0a как конец строки). Хороший скрипт фильтрует данные с помощью инструментов Unix, а не создает их. Это означает, что ваш скрипт может сломаться, потому что спецификация ввода или вывода изменилась, но не потому, что формат ввода-вывода (опять же, на самом деле отсутствует) отдельных инструментов, используемых в скрипте, изменился (потому что что-то действительно не существует не может измениться).

    Перейдя по списку базовых инструментов, есть несколько, которые я бы назвал продюсером , а не только фильтром:

    • wc – печатать количество байтов, слов, строк – очень простой формат, поэтому совершенно маловероятно изменить и, кроме того, вряд ли будет использоваться в скрипте.
    • diff – там развивались разные выходные форматы, но я не слышал о каких-либо проблемах. Также обычно не используется без надзора.
    • date – Теперь мы действительно должны заботиться о том, что мы производим, особенно в отношении языковой системы. Но в противном случае выходной формат RFC'ed, если вы точно не укажете его сами.
    • cal – давайте не будем говорить об этом, я знаю, что формат вывода сильно отличается от разных систем.
    • ls , who , w , last – я не могу помочь, если вы хотите разобрать ls, это просто не должно было быть. Кроме того, who, w, last, являются более интерактивными пользователями; Если вы используете их в сценарии, вы должны заботиться о том, что вы делаете.
    • время было указано в другом сообщении. Но да, это то же самое, что и с ls. Больше для интерактивного / местного использования. И встроенный bash сильно отличается от версии GNU, а версия GNU имеет незафиксированные ошибки в течение многих лет. Просто не полагайтесь на это.

    Вот инструменты, которые ожидают, что конкретный формат ввода более конкретный, чем байтовый поток:

    • bc , dc – калькуляторы. Уже на более хакерской стороне вещей (на самом деле, я не использую их в скриптах) и, по-видимому, очень стабильные форматы ввода-вывода.

    Есть еще одна область с гораздо более высоким риском поломки, а именно, интерфейс командной строки. Большинство инструментов имеют разные функции как в разных системах, так и на временной шкале. Примерами являются

    • Все инструменты, использующие регулярное выражение regex, могут изменять значение, основанное на локали системы (например, LC_COLLATE), и существует множество тонкостей и особенностей в реализациях регулярных выражений.
    • Просто не используйте причудливые переключатели. Вы можете легко использовать man 1p find например, для чтения справочной страницы POSIX, а не для системной man-страницы. В моей системе мне нужно установить manpages-posix.

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

    В заключение я бы сказал, что оболочка имеет потенциал быть одним из самых портативных языков (она переносима, когда вы выполняете сценарий портативно). Сравните с вашими любимыми языками сценариев, где возникают тонкие ошибки, или ваша любимая скомпилированная программа, которая будет уступать компиляции.

    Кроме того, в редких местах, где поломка может произойти из-за несовместимости, вероятно, это было бы не из-за вызванного времени, а из-за разнообразия в разных системах (что означает, что если это сработает для вас, то это произошло 20 лет назад и будет через 20 лет , слишком). Это следствие простоты инструментов.

    Существуют только де-факто стандарты IO – пробельные и нулевые выходные данные.

    Что касается совместимости, мы обычно возвращаемся к проверке номеров версий отдельных фильтров. Не то, чтобы они сильно менялись, но когда вы хотите использовать совершенно новую функцию и все еще хотите, чтобы сценарий работал в более старых версиях, вы должны каким-то образом «ifdef». Механизм представления возможностей практически не существует, за исключением случаев написания сценариев вручную.

    Сценарии разрываются, а некоторые чаще других. Старое и известное программное обеспечение имеет тенденцию оставаться относительно одинаковым, и часто имеет флаги совместимости, когда они все равно меняются.

    Сценарии, написанные на одной системе, как правило, продолжают работать, но часто ломают друг друга.

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