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

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

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

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

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

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

  • Поддержка API TWAIN на FreeBSD
  • Использовать случай предоставления файлового API для терминала / консоли
  • После fork (), где ребенок начинает свое выполнение?
  • Настройка рабочей среды - Konsole или другой терминал - открытие нескольких вкладок и запуск некоторых команд
  • Получение часовых поясов в странах
  • API ядра файловой системы
  • Почему BSD использует конкретные имена драйверов для сетевых интерфейсов? Это подразумевает ограничения?
  • Есть ли более быстрый интерфейс для информации из / proc / net / tcp?
  • 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

    Есть ли механизм, который защищает приложения во время обновления библиотеки?

    Копирование / зеркальное отображение трафика на WAN-интерфейсы без поддержки «iptables tee»

    Невозможно установить пакеты на RHEL из-за зависимостей

    Принуждение «да» к новым лицензионным соглашениям на обновление?

    Расшифруйте часть поврежденного диска

    Карта ТВ-тюнера Hauppauge с Motorola STB и LIRC

    Как я могу отправить электронную почту без использования uuencode и отключения звука?

    Настройка Xorg.conf для i915 intel driver

    Как сделать ключ переключения с помощью Autokey?

    Archbang смотреть на Archlinux

    Есть ли способ перечислить пакеты с даты, когда они вошли в архив Debian?

    Перечисление определенных строк в перечисленных файлах

    Есть ли какая-либо команда в Linux, которая заставит Linux-машину не выключать

    Шифрование и обфускация имен файлов

    Как найти активный сетевой интерфейс из пользовательского пространства?

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