При запуске скриптов в bash, я должен написать ./
в начале:
$ ./manage.py syncdb
Если я не, я получаю сообщение об ошибке:
$ manage.py syncdb
-bash: manage.py: command not found
Что является причиной этого? Я думал, .
что это псевдоним для текущей папки, и поэтому эти два вызова должны быть эквивалентны.
Я также не понимаю, почему мне не нужно ./
при запуске приложений, таких как:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(который работает без ./
)
bash
shell
unix
command-line
Дан Абрамов
источник
источник
Ответы:
Потому что в Unix, как правило, текущий каталог не находится в
$PATH
.При вводе команды оболочка просматривает список каталогов, как указано в
PATH
переменной. Текущий каталог не в этом списке.Причиной отсутствия текущего каталога в этом списке является безопасность.
Допустим, вы root и зайдите в каталог другого пользователя и наберите
sl
вместоls
. Если текущий каталог находитсяPATH
, оболочка попытается выполнитьsl
программу в этом каталоге (поскольку другойsl
программы нет). Этаsl
программа может быть вредоносной.Это работает,
./
потому что POSIX указывает, что имя команды, которое содержит a,/
будет использоваться как имя файла напрямую, подавляя поиск в$PATH
. Вы могли бы использовать полный путь для того же эффекта, но./
он короче и его легче написать.РЕДАКТИРОВАТЬ
Эта
sl
часть была просто примером. Каталоги вPATH
поиске последовательно, и когда сопоставление установлено, эта программа выполняется. Таким образом, в зависимости от тогоPATH
, как выглядит, ввода обычной команды может быть или не быть достаточно для запуска программы в текущем каталоге.источник
ls
исполняемый файл..\my.bat
т. Д., Чтобы выполнитьsl
команда, называемая паровозом, хотя по умолчанию она недоступна ;-)Когда bash интерпретирует командную строку, он ищет команды в местах, описанных в переменной среды
$PATH
. Чтобы увидеть это введите:У вас будет несколько путей, разделенных двоеточиями. Как вы увидите, текущий путь
.
обычно отсутствует$PATH
. Поэтому Bash не может найти вашу команду, если она находится в текущем каталоге. Вы можете изменить это, имея:Эта строка добавляет текущий каталог,
$PATH
чтобы вы могли сделать:Это не рекомендуется, так как имеет проблему с безопасностью, плюс у вас может быть странное поведение, которое
.
зависит от каталога, в котором вы находитесь :)Избегайте:
Как вы можете «замаскировать» какую-то стандартную команду и открыть дверь для нарушения безопасности :)
Просто мои два цента.
источник
Ваш скрипт, когда он находится в вашем домашнем каталоге, не будет найден, когда оболочка смотрит на
$PATH
переменную окружения, чтобы найти ваш скрипт../
Говорит «взгляд в текущей директории для моего сценария , а не смотря на все каталоги , указанные в$PATH
».источник
Когда вы включаете «.» по сути, вы даете «полный путь» исполняемому скрипту bash, поэтому вашей оболочке не нужно проверять переменную PATH. Без '.' ваша оболочка будет искать переменную PATH (которую вы можете увидеть, выполнив
echo $PATH
команду, чтобы увидеть, находится ли введенная вами команда в какой-либо из папок в вашем PATH. Если это не так (как в случае с manage.py), она говорит это не удается найти файл. Включение текущего каталога в переменную PATH считается плохой практикой, что достаточно хорошо объяснено здесь: http://www.faqs.org/faqs/unix-faq/faq/part2/section-. 13.htmlисточник
В * nix, в отличие от Windows, текущий каталог обычно не находится в вашей
$PATH
переменной. Таким образом, текущий каталог не ищется при выполнении команд. Вам не нужно./
запускать приложения, потому что эти приложения находятся в вашем $ PATH; скорее всего они в/bin
или/usr/bin
.источник
На этот вопрос уже есть несколько отличных ответов, но я хотел бы добавить, что, если ваш исполняемый файл находится в переменной PATH, и вы получаете очень разные результаты при запуске
к тем, которые вы получаете, если вы бежите
(допустим, вы сталкиваетесь с сообщениями об ошибках с одним, а не с другим), тогда проблема может заключаться в том, что у вас есть две разные версии исполняемого файла на вашей машине: одна на пути, а другая нет.
Проверьте это, запустив
какой исполняемый файл
и
Это исправило мои проблемы ... У меня было три версии исполняемого файла, только одна из которых была правильно скомпилирована для среды.
источник
Обоснование
/
правила POSIX PATHПравило упоминалось здесь: зачем вам нужен ./ (точка-косая черта) перед именем исполняемого файла или скрипта, чтобы запустить его в bash? но я хотел бы объяснить, почему я думаю, что это хороший дизайн более подробно.
Во-первых, полная версия правила:
/
(например./someprog
,/bin/someprog
,./bin/someprog
): УХО используется и PATH не/
(напримерsomeprog
): PATH используется, а CWD - нетТеперь предположим, что работает:
будет искать:
Затем, если вы хотите запустить
/bin/someprog
из своего дистрибутива, и вы сделали:иногда это будет работать, а в других - не получится, потому что вы можете находиться в каталоге, содержащем другую не связанную
someprog
программу.Таким образом, вы скоро узнаете, что это ненадежно, и в конечном итоге вы всегда будете использовать абсолютные пути, когда захотите использовать PATH, что приведет к поражению цели PATH.
Именно поэтому наличие относительных путей в вашем PATH - действительно плохая идея. Я смотрю на тебя
node_modules/bin
.И наоборот, предположим, что работает:
Будет искать:
Затем, если вы просто скачали скрипт
someprog
из репозитория git и хотели запустить его из CWD, вы никогда не были бы уверены, что это именно та программа, которая будет запускаться, потому что, возможно, ваш дистрибутив имеет:который находится в вашем ПУТИ из какого-то пакета, который вы установили после того, как выпили слишком много после Рождества в прошлом году.
Поэтому, опять же, вы будете вынуждены всегда запускать локальные сценарии относительно CWD с полными путями, чтобы знать, что вы запускаете:
что было бы крайне раздражающим.
Другое правило, которое вы могли бы соблазнить, было бы:
но еще раз это заставляет пользователей всегда использовать абсолютные пути для сценариев, не относящихся к PATH
"$(pwd)/someprog"
./
Правило пути поиска предлагает простое вспомнить решение о проблеме:PATH
PATH
что позволяет очень легко всегда знать, что вы выполняете, полагаясь на то, что файлы в текущем каталоге могут быть выражены как
./somefile
илиsomefile
, и поэтому придает особое значение одному из них.Иногда немного раздражает, что вы не можете искать по
some/prog
отношению кPATH
, но я не вижу более разумного решения этого.источник
Когда сценарий не находится в пути, это необходимо сделать. Для получения дополнительной информации читайте http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html.
источник
У All есть отличный ответ на вопрос, и да, это применимо только при запуске его в текущем каталоге, если только вы не указали абсолютный путь. Смотрите мои образцы ниже.
Кроме того, (точка-косая черта) имела смысл для меня, когда у меня есть команда для дочерней папки tmp2 (/ tmp / tmp2) и она использует (двойная точка-косая черта).
ОБРАЗЕЦ:
источник