Цель этого вопроса - ответить на любопытство, а не решить конкретную вычислительную проблему. Вопрос заключается в следующем: почему обязательные утилиты POSIX обычно не встроены в реализации оболочки?
Например, у меня есть сценарий, который в основном считывает несколько небольших текстовых файлов и проверяет, правильно ли они отформатированы, но для запуска на моем компьютере требуется 27 секунд из-за значительного количества операций со строками. Эта строковая манипуляция создает тысячи новых процессов, вызывая различные утилиты, отсюда и медлительность. Я довольно уверен , что если некоторые утилиты были построены, а именно grep
, sed
, cut
, tr
, и expr
, то скрипт будет работать в секунду или меньше ( на основе моего опыта в C).
Кажется, что было бы много ситуаций, в которых сборка этих утилит имела бы разницу между тем, имеет ли решение в сценарии оболочки приемлемую производительность.
Очевидно, что была причина, по которой было выбрано не делать эти утилиты встроенными. Возможно, наличие одной версии утилиты на системном уровне позволяет избежать использования нескольких неравных версий этой утилиты различными оболочками. Я действительно не могу придумать много других причин, чтобы нести накладные расходы на создание такого количества новых процессов, и POSIX достаточно определяет утилиты, так что не кажется большой проблемой иметь разные реализации, при условии, что они являются POSIX. совместимый. По крайней мере, не такая большая проблема, как неэффективность наличия такого количества процессов.
источник
printf
и т. Д.), Были включены в оболочки, когда они считались достаточно полезными.awk
обязательная утилита в POSIX, и особенно хорошо подходит (то есть, очень быстро) для реализации сценариев , которые вы могли бы реализовать с помощьюsed
,cut
,tr
,grep
иexpr
в сценарии оболочки.Ответы:
Сценарии оболочки не должны работать с такой скоростью. Если вы хотите улучшить скорость вашего скрипта, попробуйте его на Perl. Если это все еще слишком медленно, вам придется перейти на статически типизированный язык, такой как java или c, или написать модуль C для perl, который запускает слишком медленные части.
Оболочка - это первый уровень прототипирования, если вы можете доказать концепцию с помощью shell, а затем перейти к лучшему языку сценариев, который может выполнять больше проверок границ, что займет акры оболочки.
Ожидается, что ОС Unix будет включать в себя множество небольших программ, которые выполняют четко определенные задачи, составляющие большую картину. Это хорошая вещь, поскольку она разделяет большие программы. Взгляните, например, на qmail и сравните это с sendmail. qmail состоит из многих программ:
http://www.nrg4u.com/qmail/the-big-qmail-picture-103-p1.gif
Использование сетевого демона не поможет вам использовать диспетчер очереди.
источник
cd
илиpwd
.cd
является встроенным - и это действительно должно быть, потому что изменение рабочего каталога в подпроцессе не влияет на родительские процессы.Поскольку для совместимости с POSIX требуется, чтобы система 1 предоставляла большинство утилит в качестве автономных команд.
Встраивание их подразумевает, что они должны существовать в двух разных местах, внутри оболочки и снаружи. Конечно, можно было бы реализовать внешнюю версию, используя оболочку сценария оболочки для встроенной функции, но это поставило бы в невыгодное положение приложения, не являющиеся оболочкой, вызывающие утилиты.
Обратите внимание, что BusyBox пошел по вашему пути, реализовав множество внутренних команд и предоставив автономный вариант, используя ссылки на себя. Одна из проблем заключается в том, что хотя набор команд может быть довольно большим, реализации часто являются подмножеством стандарта, поэтому они не совместимы.
Обратите внимание, что по крайней мере
ksh93
,bash
иzsh
идти дальше, предоставляя пользовательские методы для запуска оболочки для динамической загрузки встроенных из общих библиотек. Технически ничто тогда не мешает всем утилитам POSIX быть реализованными и доступными как встроенные.Наконец, порождение новых процессов стало довольно быстрой операцией с современными ОС. Если вы действительно страдаете от проблемы с производительностью, возможно, будут сделаны некоторые улучшения, чтобы ваши скрипты работали быстрее.
1 POSIX.1-2008
источник
fork
не следуетexec
;fork
в настоящее время очень легкая операция по сравнению сexec
.nofork
встроенные функции busybox как на 10 раз меньше служебных данных, чемnoexec
встроенные, которые, в свою очередь, имели на ~ 5 раз меньше служебных данных, чем fork + exec отдельного двоичного файла. Определения в соответствии с unix.stackexchange.com/a/274322/29483 Интересно, что busybox неnofork
все, хотя я знаю, что некоторый код busybox сокращается из-за не очистки памяти, а просто полагается на кратковременный процесс.Из справочного руководства BASH ,
Как я уверен, вы слышали, философия UNIX в значительной степени опирается на несколько приложений, которые имеют ограниченную функциональность. У каждого встроенного есть очень веская причина, почему оно встроено. Все остальное - нет. Я думаю, что более интересный класс вопросов вдоль линий, «почему именно это
pwd
встроенный?»источник
cd
что был бы лучшим примером здесь чего-то, что невозможно реализовать в качестве отдельного инструмента.cd
должен быть встроен,pwd
нет. Так почему жеbash
разработчики решили включить его?/bin/bash
существует, но он все еще встроен. См. Список встроенных функций по адресу gnu.org/software/bash/manual/html_node/…Ребята из AT & T задали себе то же самое
Если вы посмотрите на историю AT & T Software Toolkit (в настоящее время бездействующей на github с тех пор, как основная команда ушла), то это именно то, что они сделали с оболочкой AT & T Korn, также известной как ksh93.
Производительность всегда была частью мотивации сопровождающих ksh93, и при сборке ksh вы можете выбрать создание многих распространенных утилит POSIX в качестве динамически загружаемых библиотек. Привязывая эти команды к имени каталога, например
/opt/ast/bin
, вы можете контролировать, какая версия команды будет использоваться, основываясь на положении этого имени каталога в$PATH
.Примеры:
Полный список можно найти в репозитории github ast .
Обратите внимание, что большинство инструментов ast имеют свое происхождение и будут сильно отличаться от более распространенных реализаций gnu. Исследовательская команда AT & T придерживалась официальных стандартов, что было способом достижения совместимости, когда вы не могли делиться кодом.
источник
Таким образом, мы не использовали ресурсы для оптимизации оригинального инструмента, чтобы удовлетворить каждое конкретное желание. Я думаю, что нам нужно объяснить, сколько стоило бы реализовать это конкретное желание.
это плохое предположение :-P.
Системы Post-POSIX продолжают становиться более мощными и удобными по веским причинам; в качестве стандартного факта он никогда не догоняет.
Ubuntu начала попытки перейти на упрощенную POSIX-оболочку для сценариев, чтобы оптимизировать старый процесс загрузки System V init. Я не говорю, что это не помогло, но это действительно вызвало много ошибок, которые нужно было устранить: «ошибки», скрипты, которые выполнялись
/bin/sh
, предполагая, чтоbash
функции были доступны.POSIX sh не является хорошим языком программирования общего назначения. Его основная цель - хорошо работать как интерактивная оболочка. Как только вы начнете сохранять свои команды в сценарии, имейте в виду, что вы приближаетесь к тарпиту Тьюринга . Например, невозможно обнаружить сбои в середине обычного конвейера .
bash
добавленоset -o pipefail
для этого, но это не в POSIX.Подобные полезные, но нестандартные функции предоставляются почти каждой более сложной утилитой, чем
true
.Для класса задачи, который вы наметите, вы можете нарисовать грубую линию для Awk, Perl и современного Python. Различные инструменты были созданы и развивались независимо. Вы ожидаете, что, например, GNU Awk будет включен в расширенный libutilposix?
Я не говорю, что у нас теперь есть один универсально лучший подход, на который я могу вам указать. У меня есть слабость к Python. Awk на удивление мощен, хотя меня разочаровали некоторые особенности, специфичные для GNU Awk. Но дело в том, что обработка большого количества строк по отдельности (предположительно из строк файлов) не была целью разработки оболочки POSIX.
источник
cat -@fnord foo
оболочку, он должен решить, так как он не знает, что-@
означает, что ему нужно будет вызвать фактическую команду, но, учитывая, чтоcat <foo >bar
оболочка не должна вызывать другой процесс.Существует также вопрос: в какую оболочку вы бы его встроили?
Большинство систем Unix / Linux имеют несколько различных оболочек, которые разрабатываются независимо (sh / bash / korn / ???). Если вы встраиваете инструменты в оболочку, вы получите разные реализации этих инструментов для каждой оболочки. Это может привести к накладным расходам, и вы можете столкнуться с различными функциями / ошибками, например, в grep, в зависимости от того, какую оболочку вы использовали для ее вызова.
источник
Многие ответили хорошо. Я намерен только дополнить эти ответы. Я думаю, что философия UNIX заключается в том, что инструмент должен делать одну вещь и делать это хорошо. Если кто-то пытается создать всеобъемлющий инструмент, у него гораздо больше мест для неудач. Ограничение функциональности таким образом делает набор инструментов надежным.
Кроме того, подумайте, если бы в оболочку были встроены такие функции, как sed или grep , было бы так легко вызывать их из командной строки, когда вам это нужно?
В заключение, рассмотрим некоторые функции, которые вы хотите использовать в BASH, в BASH . Например, возможность сопоставления RE в BASH реализована с использованием бинарного оператора = ~ (подробнее см. Грамматика оболочки на странице руководства , в частности, ссылка на обсуждение конструкции [[]] для if ). В качестве очень быстрого примера, скажем, я ищу в файле две шестнадцатеричные цифры:
Что касается функциональности, подобной sed , смотрите в разделе «Расширение параметров» в заголовке «Расширение» той же справочной страницы. Вы увидите множество вещей, которые вы можете сделать, которые напоминают о sed. Я чаще всего использую sed, чтобы изменить тип замены на текст. Построение вышеперечисленного:
В конце концов, является ли выше "лучше", чем?
источник
Это, наверное, историческая случайность.
Когда UNIX был создан в конце 1960-х и начале 1970-х годов, компьютеры не имели почти столько же памяти, сколько сегодня. В то время было бы возможно реализовать всю эту функциональность в виде встроенных командных оболочек, но из-за ограничений памяти им пришлось бы ограничить объем функциональности, которую они могли бы реализовать, или рисковать из-за нехватки памяти и / или перестановки подкачки. проблемы.
С другой стороны, реализуя данную функциональность как отдельные программы и выполняя два необходимых системных вызова для запуска нового процесса, насколько это возможно, они могли бы создать среду сценариев, у которой нет таких проблем и которая все еще работает с разумной скорость.
Конечно, как только эти вещи будут реализованы в виде отдельных процессов, люди будут запускать их из программ, которые не являются оболочками, а затем они должны оставаться такими, или вдруг все это программное обеспечение начнет ломаться.
Однако это не означает, что вы не можете реализовать некоторые функции дважды, и, действительно, некоторые оболочки реализуют некоторые функции, которые должны быть внешними программами в качестве встроенной оболочки; Например, Bash реализует
echo
команду как встроенную, но есть также/usr/bin/echo
источник