В чем разница между командами, встроенными в cd и cd?

17

Я столкнулся с командой Linux builtin cd.

В чем разница между командами builtin cdи cd?

На самом деле, я провел несколько исследований об этой разнице, но не смог найти замечательного и существенного объяснения этому.

Goktug
источник
1
См. Также unix.stackexchange.com/q/38808/117549
Джефф Шаллер
Смотрите также: stackoverflow.com/q/15691977/974555
gerrit

Ответы:

41

Команда cdявляется встроенной, поэтому обычно builtin cdвыполняет то же самое, что и cd. Но есть различие, если cdоно переопределено как функция или псевдоним, и в этом случае cdвызовет функцию / псевдоним, но builtin cdвсе равно изменит каталог (другими словами, встроенная функция останется доступной, даже если она перекрыта функцией).

Например:

user:~$ cd () { echo "I won't let you change directories"; }
user:~$ cd mysubdir
I won't let you change directories
user:~$ builtin cd mysubdir
user:~/mysubdir$ unset -f cd  # undefine function

Или с псевдонимом:

user:~$ alias cd='echo Trying to cd to'
user:~$ cd mysubdir
Trying to cd to mysubdir
user:~$ builtin cd mysubdir
user:~/mysubdir$ unalias cd  # undefine alias

Использование builtinтакже является хорошим способом определения cdфункции, которая что-то делает и меняет каталог (поскольку вызов cdиз нее будет просто вызывать функцию снова в бесконечной рекурсии.)

Например:

user:~ $ cd () { echo "Changing directory to ${1-home}"; builtin cd "$@"; }
user:~ $ cd mysubdir
Changing directory to mysubdir
user:~/mysubdir $ cd
Changing directory to home
user:~ $ unset -f cd  # undefine function
filbranden
источник
5
+1 Примеры особенно показательны здесь.
Ташус
2
В случае псевдонима, есть ли разница между builtin cd mysubdirи \cd mysubdir?
Gerrit
2
@gerrit Только если есть именованная функция cd, в этом случае обходится \cdпсевдоним и запускается функция. См stackoverflow.com/a/16506263/4518341
wjandrea
15

В большинстве случаев нет никакой разницы (но см. Ниже). Команда cdявляется встроенной командой во всех оболочках. Он должен быть встроен в 1, так как внешняя команда не может изменить среду вызывающей оболочки, а изменение рабочего каталога представляет собой изменение в его среде.

В bashкомандной builtinсилы оболочки использовать встроенную версию команды, несмотря на то, что может быть оболочка функции, псевдоним или внешняя команда доступна с тем же именем.

В случае, когда есть , например, функция оболочки с именем cd, то неbuiltin cd будет вызывать это. Использование позволяет обойти любые перегруженные функции, которые могут быть добавлены пользователем через функцию оболочки или псевдоним.builtin cd

Пример:

cdВстроенная команда может быть перегружена функцией , которая обновляет подсказку:

cd() {
    builtin cd "$@" && PS1=$(__update_prompt)
}

где __update_prompt- некоторая другая пользовательская функция, которая выводит строку.

Функция builtin cdin не будет вызывать функцию рекурсивно. Использование builtin cdв оболочке, где эта функция активна, дополнительно не вызовет функцию.


1 Есть Unices с внешней cdкомандой (macOS, и, я полагаю, Solaris). Цель этой команды, которая не может изменить рабочий каталог для оболочки, возможно, состоит в том, чтобы удовлетворить стандарт POSIX, который перечисляет в cdкачестве одной из внешних утилит, которые должны быть доступны ( cdне является одной из «специальных встроенных утилит») , Он может также служить в качестве теста , чтобы увидеть ли изменения каталога работы в данной директории будет возможно .

Кусалананда
источник
Кстати, MacOS также попадет в категорию ОС с внешней cdкомандой.
Йоанн
@yoann Это действительно так.
Кусалананда
Спасибо - вы сделали мой день на высшем уровне, хорошо проработанный, педантизм с сносками.
Джеймс
большинство оболочек - это внешняя программа для execlineb, но затем cd
выполнит