Вот, на мой взгляд, самое простое для понимания объяснение CFS: Process Scheduling in Linux, for kernel 3, chapter 7
Также в конце статьи есть еще ссылки по теме.
Почему обязательные утилиты POSIX не встроены в оболочку?
Поскольку для соответствия POSIX требуется система 1 для предоставления большинства утилит как отдельные команды.
Наличие их в оболочке означало бы, что они должны существовать в двух разных местах: внутри оболочки и вне ее. Конечно, можно было бы реализовать внешнюю версию, используя оболочку сценария оболочки для встроенной, но это поставило бы в невыгодное положение приложения, не являющиеся оболочкой, вызывающие утилиты.
Обратите внимание, что BusyBox пошел по предложенному вами пути, реализовав множество команд внутри и предоставив автономный вариант с использованием ссылок на самого себя. Одна проблема заключается в том, что хотя набор команд может быть довольно большим, реализации часто являются подмножеством стандарта, поэтому не соответствуют требованиям.
Также обратите внимание, что по крайней мере ksh93
, bash
и zsh
идут дальше, предоставляя настраиваемые методы для запущенной оболочки для динамической загрузки встроенных функций из разделяемых библиотек.Технически тогда ничто не мешает реализовать все утилиты POSIX и сделать их доступными как встроенные.
Наконец, создание новых процессов стало довольно быстрой операцией в современных операционных системах. Если вы действительно столкнулись с проблемой производительности, возможно, есть некоторые улучшения, чтобы ваши скрипты работали быстрее.
Однако все стандартные утилиты , включая обычные встроенные в таблицу, но не специальные встроенные ins, описанные в Специальные встроенные утилиты, , должны быть реализованы таким образом, чтобы к ним можно было получить доступ через семейство функций exec , как определено в {{1} } том Системные интерфейсы POSIX.1-2008, и может быть вызван непосредственно теми стандартными утилитами, которые в нем нуждаются (env, find, nice, nohup, time, xargs).
Также возникает вопрос: в какую оболочку вы бы ее встроили?
Большинство систем Unix / Linux имеют несколько различных оболочек, которые разрабатываются независимо (sh / bash / korn / ???). Если вы встроите инструменты в оболочку, вы получите разные реализации этих инструментов для каждой оболочки. Это вызовет накладные расходы, и вы можете столкнуться с различными функциями / ошибками, например, в grep, в зависимости от того, какую оболочку вы использовали для его вызова.
Таким образом, мы не мобилизовали ресурсы на оптимизацию исходного инструмента для удовлетворения каждого конкретного желания. Думаю, нам нужно объяснить, во сколько обойдется реализация этого конкретного желания.
В POSIX достаточно определено об утилитах, поэтому наличие различных реализаций не кажется большой проблемой.
это плохое предположение :-P.
Пост-POSIX-системы продолжают становиться более мощными и удобными по уважительным причинам; как стандарт постфактум, он никогда не догоняет.
Ubuntu начала попытки перейти на урезанную оболочку POSIX для сценариев, чтобы оптимизировать старый процесс загрузки System V init. Я не говорю, что это не удалось, но это вызвало множество ошибок, которые необходимо было устранить: «bashisms», сценарии, которые выполнялись под / bin / sh
, предполагая, что bash
особенности были доступны.
POSIX sh не является хорошим языком программирования общего назначения. Его основное предназначение - хорошо работать в качестве интерактивной оболочки. Как только вы начнете сохранять свои команды в скрипт, имейте в виду, что вы подходите к тьюрингу . Например.невозможно обнаружить сбои в середине обычного конвейера . bash
добавил для этого set -o pipefail
, но этого нет в POSIX.
Подобные полезные, но нестандартные функции предоставляются почти каждой утилитой, более сложной, чем истинное
.
Для класса задачи, которую вы намечаете, вы можете чертить черту в Awk, Perl и нынешнем Python. Различные инструменты создавались и развивались независимо. Вы бы ожидали, например, GNU Awk будет включен в состав libutilposixextended?
Я не говорю, что теперь у нас есть один универсально лучший подход, на который я могу вам указать. У меня слабость к Python. Awk на удивление мощный, хотя я был разочарован некоторыми особенностями GNU Awk. Но дело в том, что обработка большого количества строк по отдельности (предположительно из строк файлов) не была целью разработки оболочки POSIX.
Многие ответили хорошо. Я хочу лишь дополнить эти ответы. Я думаю, что философия UNIX состоит в том, что инструмент должен делать одно и делать это хорошо. Если кто-то пытается создать всеобъемлющий инструмент, у него гораздо больше возможностей для неудачи. Такое ограничение функциональности делает набор инструментов надежным.
Также учтите, что если бы в оболочку были встроены такие функции, как sed или grep , было бы так же легко вызывать из командной строки, когда вам это нужно?
В заключение учтите, что некоторые функции, которые вы хотите иметь в BASH, находятся в BASH . Например, возможность сопоставления RE в BASH реализована с помощью бинарного оператора = ~ (см. Грамматику оболочки на странице руководства для более подробной информации, в частности, обратитесь к обсуждению [[[ ]] для , если ). В качестве очень быстрого примера скажем, что я ищу в файле две шестнадцатеричные цифры:
while read line; do
if [[ $line =~ 0x[[:xdigit:]]{2} ]]; then
# do something important with it
fi
done < input_file.txt
Что касается sed-подобных функциональности, посмотрите в разделе «Расширение параметров» в заголовок «Расширение» та же справочная страница. Вы увидите множество вещей, напоминающих sed. Чаще всего я использую sed, чтобы изменить тип подстановки текста. Основываясь на вышеизложенном:
# this does not take into account the saving of the substituted text
# it shows only how to do it
while read line; do
${line/pattern/substitution}
done < input_file.txt
В конце концов, "лучше" ли вышеперечисленное, чем?
grep -E "[[:xdigit:]]{3}" input_file.txt
sed -e 's/pattern/substitution/' input_file.txt
Не ожидается, что сценарии оболочки будут выполняться с такой скоростью. Если вы хотите повысить скорость своего скрипта, попробуйте его в perl. Если это все еще слишком медленно, вам придется перейти на статически типизированный язык, такой как java или c, или написать модуль C для perl, который запускает слишком медленные части.
Оболочка - это первый уровень прототипирования, если вы можете доказать концепцию с помощью оболочки, а затем перейти к лучшему языку сценариев, который может выполнять больше проверок границ, что займет акры оболочки.
Предполагается, что ОС Unix будет включать в себя множество небольших программ, которые выполняют четко определенные задачи, составляющие большую картину. Это хорошая вещь, поскольку она разделяет более крупные программы. Взгляните, например, на qmail и сравните его с sendmail. qmail состоит из множества программ:
http://www.nrg4u.com/qmail/the-big-qmail-picture-103-p1.gif
Использование сетевого демона не поможет вам использовать диспетчер очередей. .
Если вы посмотрите на историю AT&T Software Toolkit (в настоящее время бездействует на github с момента ядра team left), именно это они и сделали с оболочкой AT&T Korn, также известной как ksh93.
Производительность всегда была частью мотивации сопровождающих ksh93, и при сборке ksh вы можете выбрать создание многих общих утилит POSIX в виде динамически загружаемых библиотек. Связывая эти команды с именем каталога, например / opt / ast / bin
, вы могли контролировать, какая версия команды будет использоваться, в зависимости от положения этого имени каталога в $ PATH
].
Примеры:
cat chmod chown cksum cmp cp cut date expr fmt head join ln
mkdir mkfifo mktemp mv nl od paste rm tail tr uniq uuencode wc
Полный список можно найти в репозитории github ast .
Обратите внимание, что большинство инструментов ast имеют собственное происхождение и будут сильно отличаться от более распространенных реализаций gnu. Команда AT&T Research соблюдала официальные стандарты, что было способом достижения взаимодействия, когда вы не могли совместно использовать код.
Из справочного руководства BASH ,
Встроенные команды необходимы для реализации функций, которые невозможно или неудобно получить с помощью отдельных утилит.
Как я уверен, вы слышали, философия UNIX в значительной степени опирается на несколько приложений, все из которых имеют ограниченную функциональность. У каждого встроенного есть очень веская причина, по которой он встроен. Все остальное - нет. Я думаю, что более интересный класс вопросов связан с тем, «почему именно является встроенным pwd
?»
Думаю, это историческая случайность.
Когда в конце 1960-х - начале 1970-х годов была создана UNIX, у компьютеров не было почти такой же памяти, как сегодня. В то время было возможно реализовать всю эту функциональность в виде встроенных команд оболочки, но из-за ограничений памяти им пришлось бы ограничить объем функциональности, которую они могли бы реализовать, или рисковать нехваткой памяти и / или мусором подкачки. проблемы.
С другой стороны, реализуя данную функциональность в виде отдельных программ и делая два требуемых системных вызова для запуска нового процесса как можно более легкими, они могли бы создать среду сценариев, в которой нет этих проблем и которая по-прежнему работает с разумной скоростью.
Конечно, как только эти вещи будут реализованы как отдельные процессы, люди будут запускать их из программ, которые являются не оболочками, и затем они должны оставаться такими, иначе все это программное обеспечение внезапно начнет ломаться.
Это не значит, что вы не можете реализовать некоторые функции дважды, и действительно, некоторые оболочки реализуют некоторые функции, которые должны быть внешней программой в виде встроенной оболочки; например, bash реализует команду echo
как встроенную, но есть также / usr / bin / echo