Зачем вам нужно./(точка-косая черта) перед исполнением или script для запуска в bash?

При запуске скриптов в bash мне нужно написать ./ в начале:

$ ./manage.py syncdb

Если я этого не сделаю, появится сообщение об ошибке:

$ manage.py syncdb
-bash: manage.py: command not found

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

Я также не понимаю, почему мне не нужно ./ при запуске приложений, таких как:

user:/home/user$ cd /usr/bin
user:/usr/bin$ git

(который работает без ./)

Ответ 1

Потому что в Unix обычно текущий каталог не находится в $PATH.

При вводе команды оболочка просматривает список каталогов, как указано в PATH. Текущий каталог не в этом списке.

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

Допустим, вы являетесь пользователем root и зайдите в другой каталог пользователя и наберите sl вместо ls. Если текущий каталог находится в PATH, оболочка попытается выполнить программу sl в этом каталоге (поскольку другой программы sl). Эта программа sl может быть вредоносной.

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

РЕДАКТИРОВАТЬ

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

Ответ 2

Когда bash интерпретирует командную строку, он ищет команды в местах, описанных в переменной окружения $PATH. Чтобы увидеть его, введите:

echo $PATH

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

PATH=$PATH:.

Эта строка добавляет текущий каталог в $PATH, чтобы вы могли:

manage.py syncdb

Рекомендован не, так как он имеет проблемы с безопасностью, плюс вы можете иметь странное поведение, поскольку . зависит от того, в каком каталоге вы находитесь:)

Избегайте:

PATH=.:$PATH

Как вы можете "замаскировать" какую-то стандартную команду и открыть дверь для нарушения безопасности:)

Только мои два цента.

Ответ 3

Ваш script, если в вашем домашнем каталоге не будет найден, когда оболочка увидит переменную среды $PATH, чтобы найти ваш script.

./ говорит: "Посмотрите в текущем каталоге для моего script, а не на все каталоги, указанные в $PATH".

Ответ 4

Когда вы включаете '.' вы по существу предоставляете "полный путь" исполняемому файлу bash script, поэтому вашей оболочке не нужно проверять вашу переменную PATH. Без '.' ваша оболочка будет выглядеть в вашей переменной PATH (которую вы можете увидеть, запустив echo $PATH, чтобы увидеть, будет ли введенная вами команда проживает в любой из папок вашего PATH. Если это не так (как в случае с manage.py) он говорит, что не может найти файл. Считается, что плохая практика включает текущий каталог на вашем PATH, который здесь объясняется достаточно хорошо: http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html

Ответ 5

В * nix, в отличие от Windows, текущий каталог обычно не находится в вашей переменной $PATH. Таким образом, текущий каталог не выполняется при выполнении команд. Вам не нужно ./ для запуска приложений, потому что эти приложения находятся в вашей $PATH; скорее всего, они находятся в /bin или /usr/bin.

Ответ 6

У этого вопроса уже есть некоторые удивительные ответы, но я хотел добавить, что если ваш исполняемый файл находится в PATH, и вы получаете очень разные выходы при запуске

./executable

к тем, которые вы получите, если вы запустите

executable

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

Проверьте это, запустив

который исполняемый

и

whereis executable

Он исправил мои проблемы... У меня было три версии исполняемого файла, только один из которых был правильно скомпилирован для среды.

Ответ 8

У всех есть большой ответ на вопрос, и да, это применимо только при его запуске в текущем каталоге, если вы не включите абсолютный путь. См. Мои образцы ниже.

Кроме того, (точка-косая черта) имела смысл для меня, когда у меня есть команда в дочерней папке tmp2 (/tmp/tmp2), и она использует (двойная точка-косая черта).

ОБРАЗЕЦ:

[fifiip-172-31-17-12 tmp]$ ./StackO.sh

Hello Stack Overflow

[[email protected] tmp]$ /tmp/StackO.sh

Hello Stack Overflow

[[email protected] tmp]$ mkdir tmp2

[[email protected] tmp]$ cd tmp2/

[[email protected] tmp2]$ ../StackO.sh

Hello Stack Overflow

Ответ 9

Существует разница между Current Directory и Working Directory, которую вы можете легко найти на google. По этой причине ваш manage.py syncdb не выполнит, как ожидалось.

Текущий каталог. Это каталог, из которого выполняется ваш shell или родительский процесс.

you are right "."  is for current directory.

В системе на базе UNIX, если у вас есть файл в /data/myfile.out, вы переходите к своему файлу через имена компонентов, которые разделены forward slash "/", поэтому если "." является вашим текущим каталогом, то если вы хотите получить доступ (выполнить в вашем случае), который находится внутри вашего текущего каталога, вам нужно будет сказать ./myexecutableFile.o. Если у вас был исполняемый файл в другой папке вашего текущего каталога, вы бы сделали что-то вроде этого ./myFiles/myexecutableFile.o. Надеюсь, у вас есть то, что я пытаюсь объяснить.