Я попытался, which cd
и он не дал путь, но вместо этого возвратил код выхода 1 (проверено с echo $?
). Сам coreutil cd
работает, поэтому исполняемый файл должен быть там, верно? Я также запустил find
для cd
, но не было показано исполняемый файл. Как это реализовано тогда?
Обновить:
Я не знаю, стоит ли спрашивать об этом в другом посте, но так как я думаю, что это хорошо, я расширяю (?) Пост ... Так что ответ был на самом деле довольно простым, для этого не существует исполняемого файла - потому что он встроенный - Но я обнаружил, что некоторые встроенные функции (оболочка bash в Fedora) имеют исполняемые файлы! Итак, встроенный -> нет исполняемого файла не правильно, я полагаю? Может быть, ответ, объясняющий, что на самом деле представляют собой встроенные функции (встроенные команды?), А здесь дело не в том, чтобы сосредоточиться больше на cd
... Некоторые опубликованные ранее хорошие ссылки указывают на то, что встроенные функции не являются программами ... так что же это? Как они работают? Это просто функции или темы оболочки?
источник
type
командуcd
нужно быть встроенным: почему компакт-диск не является программой? и этот, почемуtype
лучше, чемwhich
: почему бы не использовать "который"? Что использовать тогда?Ответы:
Команда
cd
не может быть исполняемойВ оболочке
cd
используется для «перехода в другой каталог» или, более формально, для изменения текущего рабочего каталога (CWD). Это невозможно реализовать как внешнюю команду:Каталог принадлежит процессу
Текущий рабочий каталог - это каталог, который используется для интерпретации относительных путей для получения полного пути, который можно использовать для доступа к файлам. Относительные пути используются во многих местах, и интерпретация в одном процессе не должна влиять на другой процесс.
По этой причине каждый процесс имеет свой текущий рабочий каталог.
cd
например, об изменении текущего рабочего каталога процесса оболочкиbash
.Если бы это была внешняя команда, исполняемый файл в пути, выполняющий этот исполняемый файл, создал бы процесс со своим собственным рабочим каталогом, не влияя на тот из текущей оболочки. Даже если внешняя команда изменит свой каталог, это изменение исчезнет при выходе из внешнего процесса.
Встроенные команды оболочки
Поэтому нет смысла запускать внешнюю команду для задачи
cd
. Командеcd
необходимо применить изменения к текущему процессу оболочки.Для этого это «встроенная команда» оболочки.
Встроенные команды - это команды, которые ведут себя подобно внешним командам, но реализованы в оболочке (поэтому они
cd
не являются частью coreutils). Это позволяет команде изменить состояние самой оболочки, в этом случае вызватьchdir()
see (см.man 2 chdir
);Около
which
Теперь, ответ на заглавный вопрос прост:
исполняемая команда
which
не может сказать нам, что cd является встроенной командой, потому что исполняемая команда ничего не знает о встроенных командах.альтернатива
type -a
В качестве альтернативы
which
вы можете использоватьtype -a
; Он может видеть исполняемые команды и встроенные функции; Кроме того, он видит псевдонимы и функции, также реализованные в оболочке:источник
cd
встроена оболочка.cd
это встроенная в POSIX оболочка:Хотя это явно не говорит о том, что оно должно быть встроенным, спецификация продолжает в описании
cd
:Из
bash
руководства :Полагаю, вы могли бы подумать об архитектуре, в которой
cd
не обязательно быть встроенной. Тем не менее, вы должны увидеть, что означает встроенный. Если вы напишите специальный код в оболочке, чтобы сделать что-то для какой-то команды, вы почти наверняка станете встроенным. Чем больше вы делаете, тем лучше иметь встроенную функцию.Например, у вас может быть оболочка с IPC для связи с подпроцессами, и будет
cd
программа, которая проверит наличие каталога, есть ли у вас разрешение на доступ и он, а затем свяжется с оболочкой, чтобы сообщить ей об изменении ее каталог. Однако вам нужно будет проверить, является ли процесс, общающийся с вами, дочерним (или создать специальные средства связи только с дочерними элементами, такие как специальный файловый дескриптор, разделяемая память и т. Д.), И действительно ли процесс запуск довереннойcd
программы или что-то еще. Это целая банка червей.Или у вас может быть
cd
программа, которая выполняетchdir
системный вызов, и запускает новую оболочку со всеми текущими переменными среды, примененными к новой оболочке, а затем убивает свою родительскую оболочку (каким-то образом), когда это делается. 1Хуже того, у вас может быть даже система, в которой процесс может изменять окружение других процессов (я думаю, что технически вы можете сделать это с помощью отладчиков). Однако такая система будет очень, очень уязвимой.
Вы обнаружите, что добавляете все больше и больше кода для защиты таких методов, и значительно проще просто сделать его встроенным.
То, что что-то является исполняемым файлом, не мешает ему быть встроенным. Дело в точке:
echo
а такжеtest
echo
иtest
являются утвержденными POSIX утилитами (/bin/echo
и/bin/test
). Тем не менее , почти каждый популярный корпус имеет встроенную командуecho
иtest
. Точно такkill
же встроен в программу. Другие включают в себя:sleep
(не так часто)time
false
true
printf
Однако в некоторых случаях команда не может быть чем-либо, кроме встроенного. Одним из них является
cd
. Как правило, если полный путь не указан, а имя команды совпадает с именем встроенной, вызывается функция, подходящая для этой команды. В зависимости от оболочки поведение встроенной функции и исполняемого файла может различаться (это особенно проблема, дляecho
которой характерно дикое поведение . Если вы хотите быть уверены в поведении, предпочтительно вызывать исполняемый файл с использованием полный путь, и установить переменные, какPOSIXLY_CORRECT
(даже тогда нет никакой реальной гарантии).Технически ничто не мешает вам предоставить ОС, которая также является оболочкой и имеет каждую команду как встроенную. Близко к этому крайнему концу монолитный BusyBox . BusyBox - это отдельный двоичный файл, который (в зависимости от имени, с которым он вызывается) может вести себя как любая из более чем 240 программ , включая Almquist Shell (
ash
). Если вы отключилиPATH
во время работы BusyBoxash
, программы, доступные в BusyBox, по-прежнему доступны без указанияPATH
. Они близки к тому, чтобы быть встроенными в оболочку, за исключением того, что сама оболочка является своего рода встроенной в BusyBox.Пример из практики: Оболочка Debian Almquist (
dash
)Если вы посмотрите на
dash
источник, поток выполнения выглядит примерно так (конечно, с дополнительными функциями, которые используются при использовании каналов и других вещей):main
→cmdloop
→evaltree
→evalcommand
evalcommand
затем использует,findcommand
чтобы определить, что это за команда. Если это встроенная функция, то :cmdentry.u.cmd
являетсяstruct
(struct builtincmd
), один из членов которой является указателем на функцию, с подписью типичнойmain
:(int, char **)
. Этиevalbltin
вызовы функций ( в зависимости от встроенной , является лиeval
команда или нет) либоevalcmd
, либо эта функция указатель. Фактические функции определены в различных исходных файлах.echo
Например, это :Все ссылки на исходный код в этом разделе основаны на номерах строк, поэтому они могут быть изменены без предварительного уведомления.
1 Системы POSIX имеют
cd
исполняемый файл .Примечание:
В Unix и Linux есть много отличных постов, посвященных поведению оболочки. Особенно:
cd
внешней команды?источник
cd
текст справки с помощьюhelp cd
(то же самое для всех встроенных команд оболочки)help
, это встроенный bash (для zsh, этоrun-help cd
)cd
должно быть встроено в оболочку ... но основано на том, как свойства процесса и их передача работают в UNIXcd
как встроенная оболочка, является единственной простой реализацией. Смотрите ответ Volker Siegel .Вы не можете найти исполняемый файл для,
cd
потому что нет ни одного.cd
это внутренняя команда вашей оболочки (напримерbash
).источник
от
man which
:Как видно из описания
which
, это только проверкаPATH
. Так что если вы реализовали некоторые из нихbash function
, это ничего не покажет. Лучше использоватьtype
команду вместе сwhich
.Например, в Ubuntu
ls
команда с псевдонимомls --color=auto
.И если вы реализуете тестовую функцию
hello
:which
ничего не показывает Ноtype
:В твоем случае:
Это означает, что
cd
это встроенная оболочка , она внутриbash
. Все встроенные команды bash описаныman bash
в разделе КОМАНДЫ ОБОЛОЧКИисточник
manwhich
.which
, используйтеtype
.