Почему . в пути по умолчанию?

391
alsadk

Многие говорят, что по соображениям безопасности текущий каталог не находится в $PATHпеременной, и Linux не просматривает текущий каталог, чтобы узнать, доступна ли конкретная команда из этого каталога. но я сделал cd /usr/binтогда, lsи это работало просто отлично; также я сделал echo $PATHи вывод содержит /usr/bin.

Вы должны заметить, что по соображениям безопасности текущий каталог отсутствует в $PATHпеременной, и Linux не просматривает текущий каталог, чтобы узнать, доступна ли конкретная команда из этого каталога.

Руководство по сертификации Red Hat® RHCSATM / RHCE® 7 от Сандера ван Вугта

Почему я могу бежать ls, находясь в /usr/bin?

0

2 ответа на вопрос

4
Glorfindel

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

Это правда, но это действительно искать во всех каталогах, указанных в $PATH, даже если вы могли бы быть в таком каталоге на данный момент.

Другими словами, если .его нет в вашем $PATH, не имеет значения, где вы находитесь, он всегда будет искать в тех же каталогах, чтобы узнать, доступна ли там конкретная команда.

Но, как я понял, текущий каталог не должен быть в $ PATH, почему он все еще находится в $ PATH после того, как я перешел в каталог / usr / bin? «Вы должны заметить, что по соображениям безопасности текущий каталог отсутствует в переменной $ PATH, и Linux не просматривает текущий каталог, чтобы узнать, доступна ли определенная команда из этого каталога». Red Hat® RHCSATM / RHCE® 7 Cert Guide Сандер ван Вугт alsadk 5 лет назад 0
Это просто означает, что он * обычно * не смотрит в текущем каталоге (в отличие от Windows, которая делает). Glorfindel 5 лет назад 1
Так что Linux не смотрит в текущий каталог, если он не находится в $ PATH, я прав? alsadk 5 лет назад 0
Да, и если `.` находится в` $ PATH`, он * всегда * будет смотреть в текущем каталоге. Glorfindel 5 лет назад 2
0
Kamil Maciorowski

Этот другой ответ хорош, но обсуждение в комментариях указывает, что более широкое объяснение может быть полезным.

Этот документ описывает, в какой последовательности POSIX-совместимая оболочка должна искать команды. Это очень общий, не самый простой способ понять. Вместо того, чтобы анализировать эту крайне абстрактную процедуру, давайте посмотрим, как действует реальная оболочка.

Если предположить,

  • ваша $PATHвыглядит так /usr/local/bin:/usr/bin:/bin:;
  • ты в Баш;
  • вы печатаете lsи нажимаете Enter;
  • нет ls псевдонима, который бы изменил команду на что-то другое ls;

тогда Bash запустит первый существующий lsобъект из списка ниже. Именно этот список с учетом вашего случая.

  1. ls функция.
  2. lsвстроенный (обычно lsэто не встроенный в Bash; но так как Bash может динамически загружать новые встроенные команды, вы можете создать lsвстроенный).
  3. lsисполняемый файл с полным путевым именем, хранящимся в хэш-таблице (это произойдет, если когда-то в прошлом lsисполняемый файл был найден в соответствии со следующим пунктом и он все еще запоминается).
  4. lsисполняемый файл из $PATH. В вашем случае последовательность:
    1. /usr/local/bin/ls
    2. /usr/bin/ls
    3. /bin/ls

Обратите внимание, что нет ./lsв процедуре; ни в какой момент ваш текущий рабочий каталог не принимается во внимание, особенно если он не сопоставлен с записями в $PATH.

Теперь это утверждение

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

только означает, что ./lsв приведенном выше списке нет жестко заданного кода. Он появится в списке, если вы $PATHсодержали, .но

по соображениям безопасности текущий каталог не находится в $PATHпеременной

Я объясню эти причины позже в ответе. Тем не менее, вы можете добавить .в $PATHсвой собственный. В этом случае ./lsпоявится в списке как 4.x запись. Сравните это с Windows, которая будет искать lsв текущем рабочем каталоге, независимо от того, находится он в $PATHили нет. Если бы Linux делал то же самое, то всегда была бы ./lsзапись, жестко закодированная где-то выше пункта 3 нашего списка.

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

  • оболочка никогда не использует буквальный ./lsпуть, процедура возвращает /usr/bin/ls;
  • тот факт, что вы находитесь, ничего не/usr/bin значит ;
  • Дело /usr/binв том, много$PATH значит .

Но если бы вы имели .в качестве первой записи в вашем $PATHтогда

  • оболочка будет использовать буквальный ./lsпуть;
  • факт, в котором вы находитесь, /usr/binбудет много значить ;
  • Факт /usr/binв том, $PATHчто ничего не значит .

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

Стоит также отметить, что утверждения типа «мой текущий рабочий каталог находится в моем $PATH» или «Я в каталоге, который находится в моем $PATH» не рассказывают всей истории. Они могут означать:

  • " /some/particular/directoryв моем, $PATHи я в /some/particular/directoryданный момент"

или же

  • «буквальная .запись в моем $PATH».

Как показано, два случая различаются.


Похоже, вы ожидали, что вас lsне найдут только потому, что вы оказались в его каталоге. Ну, это было бы неудобно, в то время как не было бы никакого преимущества безопасности вообще. Основная причина безопасности для не имеющих в .качестве фиксированного шага в общей последовательности поиска команд и для не имеющих .в $PATHразъясняются в этом UNIX FAQ :

Рассмотрим, что происходит в случае, когда .первая запись в PATH. Предположим, что ваш текущий каталог является общедоступным для записи, например /tmp. Если окажется, что программа, названная /tmp/lsдругим пользователем, осталась там, и вы ввели ls(намереваясь, конечно, запустить обычную /bin/lsпрограмму), вместо этого будет запущена ваша оболочка ./ls, программа другого пользователя. Излишне говорить, что результаты запуска неизвестной программы, как эта, могут вас удивить.

Там нет смысла запрещать /usr/bin/lsтолько потому, что вы в /usr/bin. Если lsимеется вредоносное ПО, вы, вероятно, уже запустили его, работая в другом каталоге, или в конце концов запустите его, работая в другом каталоге.


ТЛ; др

Подводя итог, lsв вашем примере работает, потому что это то, /usr/bin/lsчто найдено, а не ./ls. Тот факт, что последний путь переходит в первый, не имеет значения, потому что последний путь не используется в первую очередь. Он не используется, потому что «Linux не смотрит в текущий каталог…» (то есть он не смотрит в .). /usr/binТем не менее, это выглядит, потому что это в вашем $PATH.

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