Я много раз видел консольные команды вроде
./redis-server
или
./mongo
что именно ./ средства?
Когда вы запускаете команду без префикса, системы Unix ищут команду в PATH
. Например, если вы наберете ls
тогда Unix будет проходить все пути, перечисленные в PATH
найти ls
двоичный.
Например, предположим, что ваш PATH
установлен на /bin:/usr/bin:/usr/local/bin
тогда просто набираю ls
заставит вашу оболочку найти команду в /bin/ls
и выполнить его.
Системы Unix должны оценивать пути в том порядке, в котором они перечислены в PATH
. Итак, если у вас несколько ls
установлен, он выполнит найденный первым, игнорируя другие. Итак, в приведенном выше примере у вас может быть другой ls
установлен в /usr/local/bin/ls
который никогда не используется, если вы просто набираете ls
. Если вы хотите выполнить /usr/local/bin/ls
вместо этого вы можете либо изменить PATH
или используйте абсолютный ввод пути /usr/local/bin/ls
.
Теперь дело доходит до вашего ./
префикс. В .
просто ссылается на текущую папку. Итак, если вы добавите к команде префикс ./
ваша оболочка ищет команду в текущей папке. по факту
./command
идентичен
`pwd`/command
или (на BASH)
${PWD}/command
Как уже упоминалось в командной строке Windows, вы можете просто ввести command
если вы хотите выполнить command.exe
из текущей папки. Это связано с тем, что Windows сначала неявно ищет двоичный файл в текущей рабочей папке перед поиском пути.
К сожалению, это небезопасно. Представим, что я хотел бы украсть информацию о пользователе, к которой у меня нет доступа как у обычного пользователя. Я просто помещу в свой домашний каталог очень простой скрипт под названием ls со следующим содержимым:
#!/bin/bash
cp /etc/shadow /home/my-user > /dev/null 2>&1
chown my-user /home/my-user/shadow > /dev/null 2>&1
/bin/ls $*
Затем сделайте его исполняемым.
Затем я звоню своему системному администратору и рассказываю ему историю о некоторых довольно странных именах файлов в моем домашнем каталоге. Скорее всего, администратор входит в оболочку (надеюсь, как root) cd в мой каталог и выполняет ls
. Что произойдет, если вместо /bin/ls
системный администратор выполнит мой ls
скрипт, который просто помещает копию /etc/shadow
в мою домашнюю папку. Что ж, администратор, наверное, поинтересовался бы, почему это ls
не будет перечислять имена файлов. Таким образом, сценарий просто выполняет «настоящую» /bin/ls
команда в последней строке.
Поэтому, чтобы предотвратить такие проблемы, большинство современных систем Unix не включают текущий каталог (.
) в пути поиска. Обычно, если команда выполняется без указания полного пути, оболочка будет просто выполнять двоичные файлы в пределах пути, который обычно включает только доверенные пути (не доступные для записи пользователем). Когда ты видишь ./mongo
в документации это просто означает, что вы должны убедиться, что mongo
из правильной папки, а не из какой-то mongo
двоичный файл где-то на пути.
Если вы часто запускаете двоичные файлы по текущему пути, вы можете просто добавить "." в список PATH вручную:
export PATH=".:$PATH"
Начиная с этого момента оболочка всегда будет сначала искать двоичные файлы в текущем каталоге. Как было написано выше, это очень опасно, так как вам придется проверять текущий рабочий каталог на наличие двоичных файлов каждый раз, когда вы выполняете команду - даже перед ее выполнением. К сожалению, чтобы проверить текущий каталог на наличие двоичных файлов, вы обычно используете ls, который уже может выполнять двоичный файл, которого вы не ожидаете.
Лично я часто использую в своих $HOME/.profile
:
export PATH="~/bin:$PATH"
Это позволяет мне помещать некоторые скрипты в свой $HOME/bin
папку и запускать их, не указывая полный путь. Но помните, что $HOME/bin
для меня тоже надежный путь.
Еще одно небольшое примечание. Каждый каталог (даже пустой) содержит две жесткие ссылки. Проверьте ls -a
вывод:
.
..
В .
запись относится к текущему каталогу, а ..
запись жестко связана с родительским каталогом. Это позволяет относительные пути. Конечно, он также допускает рекурсивные определения, такие как ././././././command
выполнить command
так как .
всегда относится к одному и тому же каталогу. Вы также можете выполнить что-то вроде /bin/../bin/./././../bin/ls
что полностью верно.
Надеюсь, это немного проясняет, что .
и ..
записи о.
.
это текущий каталог. Таким образом, команда сообщает оболочке искать исполняемый файл в текущем каталоге.
Не путать с . foo
, это совершенно другая команда.