Почему ls
требуется отдельный процесс для его выполнения? Я знаю причину, по которой команды наподобие cd
не могут быть выполнены механизмом разветвления, но есть ли вред, если они ls
выполняются без разветвления?
ls
cd-command
fork
crisron
источник
источник
ls
это внешняя программаecho *
илиecho * .*
(в зависимости от параметров оболочки) довольно неплохо выполняет распечатку файлов без разветвления.ls-F
которая действует какls -F
. Это для эффективности. Вы всегда получаете-F
что обычно хорошая идея. Если вы укажете какие-либо другие параметры, они будут добавлены к внешней команде.Ответы:
Ответ более или менее
ls
- внешний исполняемый файл. Вы можете увидеть его местоположение, запустивtype -p ls
.Почему тогда не
ls
встроен в оболочку? Ну почему так должно быть? Задача оболочки состоит не в том, чтобы охватить все доступные команды, а в том, чтобы обеспечить среду, способную их выполнять. У некоторых современных оболочек естьecho
,printf
и их аналог как встроенные, которые технически не обязательно должны быть встроенными, но сделаны из соображений производительности, когда они запускаются многократно (в основном в тесных циклах). Не делая их встроенными, оболочка должна была бы форкать и выполнять новый процесс для каждого вызова к ним, который может быть очень медленным.По крайней мере, запуск
ls
внешнего исполняемого файла требует выполнения одного из системных вызовов семейства exec. Вы можете сделать это без разветвления, но это заменит основную оболочку, которую вы используете. Вы можете увидеть, что происходит в этом случае, выполнив следующие действия:Поскольку образ процесса вашей оболочки заменен, текущая оболочка больше не доступна после этого. Чтобы оболочка могла продолжать работать после запуска ls, команда должна быть встроена в оболочку.
Форкинг позволяет заменить процесс, который не является вашей основной оболочкой, что означает, что вы можете продолжить запускать свою оболочку впоследствии.
источник
echo
,printf
и т.д.cd
не внешний исполняемый файл?cd
исполняемый файл ( см. Здесь ). Если вы хотите использовать chdir () в текущем процессе, вам нужно встроить его в оболочку.ls
она внешняя, но она также может быть реализована в оболочке. Смотрите busybox.В Bash Reference Manual гласит:
То есть оболочки предназначены для включения только встроенных команд, если:
Команда
ls
не соответствует ни одному из вышеуказанных требований.Однако здесь нет программных ограничений, которые бы препятствовали
ls
внедрению в качестве встроенного, который выполняется в том же процессе, что и интерпретатор bash. Причины, по которым команды не внедряются в состав встроенных командных оболочек:Что касается первой причины - вы хотите, чтобы оболочка была как можно более независимой и устойчивой. Вы не хотите, чтобы оболочка зависала
ls
при монтировании NFS, которое «не отвечает, все еще пытается».Что касается второй причины - во многих случаях вы можете использовать оболочку для системы, которая использует Busybox или другую файловую систему, которая имеет другую
ls
реализацию. Или даже использовать один и тот же источник оболочки в ОС, которые имеют разныеls
реализации.Что касается третьей причины - для таких выражений
find . -type d | xargs ls -lad
было бы трудно или невозможно реализовать ихls
в том же процессе, что и интерпретатор оболочки.Что касается четвертой причины - выполнение некоторых
ls
команд может занять много времени. Возможно, вы захотите, чтобы оболочка продолжала делать что-то еще в это время.Примечание: Смотрите этот полезный пост по Уоррен Янг в ответ на подобный вопрос.
источник
ls
во внешний процесс. Это может быть сделано, но это будет сложно.bash
выводalias | grep ls
. входcat /etc/passwd | while read a; do echo "$a"; done
ls
не требует отдельного процесса. Очень немногие команды фактически требуют отдельного процесса: только те, которые должны изменить привилегии.Как правило, оболочки реализуют команды как встроенные, только когда эти команды должны быть реализованы как встроенные. Команды , как
alias
,cd
,exit
,export
,jobs
, ... нужно прочитать или изменить некоторое внутреннее состояние оболочки, и , следовательно , не могут быть отдельные программы. Команды, которые не имеют таких требований, могут быть отдельными командами; таким образом, они могут быть вызваны из любой оболочки или другой программы.Глядя на список встроенных команд в bash, только следующие встроенные функции могут быть реализованы в виде отдельных команд. Для некоторых из них возможна небольшая потеря функциональности.
command
- но он потеряет свою полезность в ситуациях, когда онPATH
может быть неправильно настроен, и сценарий используетсяcommand
как часть его настройки.echo
- это встроенный для эффективности.help
- он может использовать отдельную базу данных, но встраивание текста справки в исполняемый файл оболочки имеет то преимущество, что делает исполняемый файл оболочки автономным.kill
- наличие встроенной функции имеет два преимущества: она может распознавать обозначения заданий в дополнение к идентификаторам процессов и может использоваться даже тогда, когда не хватает ресурсов для запуска отдельного процесса.printf
- по той же причинеecho
, что и для поддержки-v
возможности помещения вывода в переменную.pwd
- встроенная функция предоставляет дополнительную возможность логического отслеживания текущего каталога (оставляя символические ссылки без изменений, а не расширяя их).test
- это встроенная система для повышения эффективности (и bash также работает с файлами, вызываемыми/dev/fd/…
в некоторых операционных системах).Несколько оболочек предлагают значительное количество дополнительных встроенных элементов. Есть sash , представляющий собой оболочку, разработанную как отдельный двоичный файл для аварийного ремонта (когда некоторые внешние команды могут быть недоступны). Он имеет встроенный
ls
, вызываемый-ls
, а также другие инструменты, такие как-grep
и-tar
. Встроенные Sash-возможности имеют меньше возможностей, чем полноценные команды. Zsh предлагает несколько подобных встроенных функций в своем модуле zsh / files . Он не имеетls
, но подстановочный знак расширения (echo *
) иzstat
может выполнять аналогичную функцию.источник
Я думаю, что здесь чего-то не хватает людям, это сложная программа GNU
ls
на Linux. Сравнивая размер исполняемого файлаls
с оболочкойbash
anddash
в моей системе Debian, мы видим, что он довольно большой:Включение такой
ls
же полнофункциональной версии, как в версии GNUbash
, увеличит размер исполняемого файла на 10%. Это почти такой же размер, как полнаяdash
оболочка!Большинство встроенных команд оболочки выбраны потому, что они интегрируются с оболочкой таким образом, что внешние исполняемые файлы не могут (вопрос указывает на это
cd
, но другой пример - это версияkill
интеграции bash с управлением заданиями bash) или потому, что они представляют собой очень простые для реализации команды, давая большую скорость против размера выплаты (true
иfalse
примерно так же просто, как он получает).У GNU
ls
был длинный цикл разработки, и он может реализовывать различные опции для настройки того, какие / как результаты отображаются. Использование встроенных ls по умолчанию либо потеряло бы эту функциональность, либо значительно увеличило бы сложность и размер оболочки.источник
cd
встроен в оболочку,ls
это отдельная программа, которую вы увидите/bin/ls
.источник
Это сделать то, что вы ищете:
Также вы можете хранить имена файлов в массиве:
Но он не заботится о пробелах в именах.
Он переходит к переменной и заботится о пробелах:
источник