Почему не был бы, 'которые' управляют работой для 'CD'? Я не могу найти исполняемый файл для 'CD' также!

Я попробовал which cd и это не дало путь, но вместо этого возвратило код выхода 1 (сверенный echo $?). coreutil cd самостоятельно работает, таким образом, исполняемый файл должен быть там, правильно? Я также выполнил a find для cd, но не было никакого показанного исполняемого файла. Как это реализовано затем?

Обновление:

Я не знаю, должен ли я спросить это в другом сообщении, но так как я думаю, что это хорошо здесь, я разворачиваю (?) сообщение... Таким образом, ответ был на самом деле довольно прост, нет никакого исполняемого файла для того — потому что это - встроенное — Но я нашел, что некоторые builtins (оболочка удара в Fedora) имеют исполняемые файлы! Таким образом встроенный-> никакой исполняемый файл не является правильным, что я предполагаю? Возможно, ответ, объясняющий, что на самом деле builtins (встроенные команды?), который на самом деле является вопросом здесь, вместо того, чтобы фокусироваться больше на cd... Некоторые хорошие ссылки, отправленные ранее, указывают, что builtins не являются программами... поэтому, каковы они? Как они работают? Они, просто функционирует или потоки оболочки?

30
задан 17 May 2015 в 23:01

4 ответа

Команда cd не может быть исполняемый файл

В оболочке, cd используется, чтобы "войти в другой каталог", или более официально, изменить текущий рабочий каталог (CWD). Невозможно реализовать это как внешнюю команду:

Каталог принадлежит процессу

Текущий рабочий каталог является каталогом, который используется для интерпретации относительных путей для получения полного пути, который может привыкнуть к файлам доступа. Относительные пути используются во многих местах, и интерпретация в одном процессе не должна влиять на другой процесс.
Поэтому каждый процесс имеет свой собственный текущий рабочий каталог.

cd об изменении текущего рабочего каталога процесса оболочки, например bash.

Если бы это была внешняя команда, то исполняемый файл в пути, выполняя тот исполняемый файл создал бы процесс со своим собственным рабочим каталогом, не влияя на ту из текущей оболочки. Даже если внешняя команда изменилась бы, это - каталог, то изменение уходит, когда внешний процесс выходит.

Shell встроенные команды

Таким образом, не имеет никакого смысла выполнять внешнюю команду для задачи cd. Команда cd потребности применить изменение в в настоящее время рабочем процессе оболочки.

Чтобы сделать это, это - “встроенная команда” оболочки.

Встроенные команды являются командами, которые ведут себя подобные внешним командам, но реализованы в оболочке (так cd не часть coreutils). Это позволяет команде изменять состояние самой оболочки, в этом случае звонить chdir() посмотрите (см. man 2 chdir);

О нас which

Теперь, ответ на вопрос о заголовке легок:
Исполняемая команда which не может сказать нам, что CD является встроенной командой, потому что исполняемая команда ничего не знает о builtins.

Альтернатива type -a

Как альтернатива which, можно использовать type -a; Это видит исполняемые команды и builtins; Кроме того, это видит псевдонимы и функции - также реализованный в оболочке:

$ type -a cd
cd is a shell builtin
$ type -a type
type is a shell builtin
$ type -a which
which is /usr/bin/which
which is /bin/which
46
ответ дан 23 November 2019 в 00:45

Вы не можете найти исполняемый файл для cd, потому что нет ни одного.

cd внутренняя команда Вашей оболочки (например, bash).

8
ответ дан 23 November 2019 в 00:45

cd переданная под мандат POSIX встроенная оболочка:

Если простая команда приведет к названию команды и дополнительному списку аргументов, то следующие действия должны быть выполнены:

  1. Если название команды не будет содержать наклонных черт, то первый успешный шаг в следующей последовательности должен произойти:
    ...
    • Если название команды будет соответствовать названию утилиты, перечисленной в следующей таблице, то та утилита должна быть вызвана.
      ...
      cd
      ...
    • Иначе команда должна искаться использование ПУТИ...

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

Так как CD влияет на текущую среду выполнения оболочки, он всегда обеспечивается как оболочка, регулярная встроенный.

От bash руководство:

Следующая оболочка встроенные команды наследована от Оболочки Bourne. Эти команды реализованы, как указано стандартом POSIX.
...

cd
       cd [-L|[-P [-e]]] [directory]

Я предполагаю это, Вы могли думать об архитектуре где cd не должно быть встроенное. Однако необходимо видеть то, что подразумевает встроенное. При написании специального кода в оболочке, чтобы сделать что-то для некоторой команды, Вы рядом с наличием встроенного. Чем больше Вы делаете, тем лучше это должно просто иметь встроенное.

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

Или у Вас мог быть a 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 программ, включая Shell Almquist (ash). Если Вы сбрасываете PATH при выполнении BusyBox ash, программы, доступные в BusyBox, все еще доступны для Вас, не указывая a PATH. Они близко подходят к тому, чтобы быть оболочкой builtins, за исключением того, что сама оболочка является своего рода встроенным к BusyBox.


Тематическое исследование: Shell Debian Almquist (dash)

Если Вы смотрите на dash источник, поток выполнения - что-то вроде этого (конечно, с дополнительными функциями, включенными, когда каналы и другие вещи используются):

maincmdloopevaltreeevalcommand

evalcommand затем использование findcommand определить, какова команда. Если это - встроенное, то:

 case CMDBUILTIN:
     if (spclbltin > 0 || argc == 0) {
         poplocalvars(1);
         if (execcmd && argc > 1)
             listsetvar(varlist.list, VEXPORT);
     }
     if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
         if (exception == EXERROR && spclbltin <= 0) {
             FORCEINTON;
             break;

cmdentry.u.cmd a struct (struct builtincmd), один из чей участников являются указателем функции с подписью, типичной для main: (int, char **). evalbltin вызовы функции (в зависимости от того, является ли встроенное eval команда или не) также evalcmd, или этот указатель функции. Фактические функции определяются в различных исходных файлах. echo, например:

int
echocmd(int argc, char **argv)
{
    int nonl;

    nonl = *++argv ? equal(*argv, "-n") : 0;
    argv += nonl;

    do {
        int c;

        if (likely(*argv))
            nonl += print_escape_str("%s", NULL, NULL, *argv++);
        if (nonl > 0)
            break;

        c = *argv ? ' ' : '\n';
        out1c(c);
    } while (*argv);
    return 0;
}

Все ссылки на исходный код в этом разделе основаны на номере строки, таким образом, они могут измениться без уведомления.


1 система POSIX действительно имеет a cd исполняемый файл.


Примечание стороны:

Существует много превосходных сообщений на Unix & Linux, которые имеют дело с поведением оболочки. В особенности:

Если Вы не заметили шаблон в вопросах, перечисленных до сих пор, почти все они вовлекают Stéphane Chazelas.

28
ответ дан 23 November 2019 в 00:45

от man which:

то, которое возвращает пути файлов (или ссылки), который был бы выполнен в текущей среде, имело ее аргументы, данный как команды в строго совместимой на POSIX оболочке. Это делает это путем поиска ПУТИ исполняемые файлы, соответствующие названиям аргументов. Это не переходит по символьным ссылкам.

Поскольку мы видим из описания which, это только проверяет PATH. Таким образом, если Вы реализовали некоторых bash function, это ничего не покажет Вам. Лучше использовать type команда наряду с which.

Например, в Ubuntu ls команда, искаженная к ls --color=auto.

$ type ls
ls is aliased to `ls --color=auto'

$ which ls
/bin/ls

И если Вы реализуете тестовую функцию hello:

$ function hello() { for i in {1,2,3}; do echo Hello $i;done }
$ which hello

which шоу ничто. Но type:

$ type hello
hello is a function
hello () 
{ 
    for i in {1,2,3};
    do
        echo Hello $i;
    done
}

В Вашем случае:

$ type cd
cd is a shell builtin

Это означает это cd встроенная оболочка, это внутри bash. Весь удар builtins описанный в man bash, в разделе SHELL BUILTIN COMMANDS

SHELL BUILTIN COMMANDS
       Unless otherwise noted, each builtin command documented in this section
       as accepting options preceded by - accepts -- to signify the end of the
       options.   The  :, true, false, and test builtins do not accept options
       and do not treat -- specially.  The exit, logout, break, continue, let,
       and  shift builtins accept and process arguments beginning with - with‐
       out requiring --.  Other builtins that accept  arguments  but  are  not
       specified  as accepting options interpret arguments beginning with - as
       invalid options and require -- to prevent this interpretation.
7
ответ дан 23 November 2019 в 00:45

Другие вопросы по тегам:

Похожие вопросы: