При выполнении программы на C, a.out
, используя терминал Ubuntu, почему мне всегда нужно набирать ./
перед a.out
, а не просто писать a.out
? Есть ли решение для этого?
Когда вы набираете название программы, например a.out
, система ищет файл в вашей переменной PATH. В моей системе PATH установлен на
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Ваш, вероятно, похож. Для проверки введите echo $PATH
в терминале.
Система просматривает эти каталоги в указанном порядке, и если она не может найти программу, выдается ошибка command not found
.
Добавление команды к ./
фактически говорит: «забудьте о PATH, я хочу, чтобы вы смотрели только в текущем каталоге».
Аналогично, вы можете указать системе искать только в другом определенном месте, добавив к команде относительный или абсолютный путь, такой как:
../
означает в родительском каталоге, например, ../hello
ищет привет в родительском каталоге.
./Debug/hello
: «искать hello
в подкаталоге Debug моего текущего каталога.»
или /bin/ls
: «искать ls
в каталоге /bin
»
По умолчанию текущий каталог не находится в пути, поскольку считается угрозой безопасности. См. Почему. по умолчанию не в пути? в Superuser почему.
Можно добавить текущий каталог в вашу переменную PATH, но по причинам, указанным в связанном вопросе, я бы не рекомендовал его.
Причина этого проста.
Предположим, у вас есть команда с тем же именем, что и у приложения в текущем каталоге. Затем выполнение команды в оболочке вызовет ваше приложение вместо встроенной команды. Это было бы проблемой безопасности, если ничего больше.
Требуя, чтобы ./
использовалось спереди, оболочка знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с этим именем.
$ gcc hello.c -o /path/to/someplace/hello
создаст исполняемый файл в некотором месте. Если это место находится на вашем пути, вы сможете запустить файл. Вы можете написать это, если хотите создать ярлык для действия «скомпилируйте этот исходный код с помощью gcc и поместите исполняемый файл в какое-то место, которое находится на вашем пути»
Я бы посоветовал вам создать новый каталог с именем "testbin" или что-то в этом роде и поместите его на свой путь, чтобы сохранить существующие каталоги путей чистыми.
./
выполняет файлы, которые не находятся в Вашем $PATH
, скорее это выполняет файл в текущем каталоге (или другой через ./home/stefano/script.sh
). Теперь, ПУТЬ является переменной среды, которая содержит все места, где удар может искать исполняемые программы, не имея всего (абсолютного) пути к ним.
Это разделение необходимо, чтобы не петлять. Т.е. если Вам назвали файл ls
в Вашем корневом каталоге это не находиться в Вашем ПУТИ будет препятствовать тому, чтобы удар путал его с реальным ls
. Переменная ПУТИ также определяет поисковый порядок:
exec
syscall (специальный метод Ядра, как программы запущены), система ищет файл путем прохождения через каждого из каталогов в ПУТИ. После того как программа была найдена, даже если это находится в нескольких каталогах, поиск прерван, и первый найденный выполняется.Для петляния необходимо будет установить исполняемый бит в полномочиях:
Так как Вы уже находитесь на командной строке, можно просто ввести chmod +x finename
.
Или можно установить полномочия путем щелчка правой кнопкой по файлу и выбора Свойств:
Можно теперь скопировать файл в любой из каталогов в ПУТИ, для наблюдения, которые там - и они установлены на основе в расчете на пользователя - тип echo $PATH
.
stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Если Вы создаете исполняемый файл, cat
, и переместите его в /usr/local/sbin
, это выполняется вместо надлежащего cat
, который находится в /bin
. Можно узнать, где файлы при помощи type cat
и whereis cat
.
«./» имеет смысл, когда вы запускаете программу, известную для вас и конкретную, например, свой собственный. Эта программа должна присутствовать в вашем текущем каталоге. «./» не имеет смысла, когда вы запускаете стандартную команду, которая находится где-то в $ PATH. Команда «какая команда запускается» сообщает вам, где находится команда запуска в $ PATH.
./
прежде, чем выполнить программу?В терминале, каждый раз, когда Вы вводите имя приложения, скажем, gedit
, терминал пойдет посмотреть в некоторых (предопределенных) каталогах, которые содержат приложения (двоичные файлы приложений). Названия этих каталогов содержатся в названной переменной PATH
. Вы видите то, что находится в этой переменной путем выполнения echo $PATH
. См. те каталоги, разделенные :
? Это - каталоги, в которых терминал пойдет поиск, если Вы просто введете gedit
, nautilus
, или a.out
. Как Вы видите, путь Вашего a.out
программа не там. Когда Вы делаете ./a.out
, Вы говорите, что терминал "выглядит в текущем каталоге и работает a.out
, и не пойдите посмотреть в PATH
.
Если Вы не хотите вводить ./
каждый раз необходимо будет добавить a.out
каталог в $PATH
. В следующих инструкциях я предположу что путь к a.out
/path/to/programs/
, но необходимо изменить его на фактический путь.
Просто добавьте следующую строку в конец файла ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Источник: Персистентные переменные среды
Выйдите из системы и войдите в. Вы теперь сможете работать a.out
без ./
из любого каталога.
Если у Вас есть другие программы в других каталогах, можно просто добавить тех, которые к вышеупомянутой строке. Однако я советовал бы, чтобы иметь один каталог, названный "myPrograms", например, и подвергнуть все Ваши программы под ним.
Примечание: изменение
userName
к Вашему фактическому имени пользователя Ubuntu.
Что, если у Вас есть другие программы, Вы хотите выполнить? И они - все в различных папках? Ну, "более организованное" решение состояло бы в том, чтобы создать названную папку bin
в соответствии с Вашим Корневым каталогом, и добавляют символьные ссылки (ярлыки) под той папкой. Вот то, как:
mkdir /home/userName/bin
bin
в соответствии с Вашим Корневым каталогом.ln -s /path/to/programs/a.out /home/userName/bin
a.out
программа под bin
.Выйдите из системы и войдите в. Вы теперь сможете работать a.out
без ./
из любого каталога.
Теперь, каждый раз, когда у Вас есть другая программа где-либо еще, скажем, программа b.in
на Вашем Рабочем столе все, что необходимо сделать: ln -s /home/userName/Desktop/b.in /home/userName/bin
, и Вы затем сможете выполнить его без ./
также.
Примечание: благодаря комментарию @Joe, когда Вы делаете резервные копии, символьные ссылки должны быть обработаны особенно. По умолчанию,
rsync
не обрабатывает их вообще, поэтому когда Вы восстанавливаете, они не там.
./
устраняет ненужный поиск пути. ./
заставляет искать только в текущем каталоге. Если мы не дадим ./
, он будет искать различные пути, заданные в системе, такие как /usr/bin
, /usr/sbin/
и т. Д.
". /" означает, что Вы хотите выполнить файл в текущем каталоге, это - ярлык для ввода целого пути, например:
[root@server ~]#/path/to/file/file.pl
то же как:
[root@server file]#./file.pl
в предыдущем примере Вы прошли каталог и его каталоги глотка к расположению файла и использовали ". /" для петляния в текущем каталоге.
тот перед ним" [root@server ~] #/path/to/file/file.pl" также выполнит файл если Вы ленивый к "CD" Ваш путь к расположению файла.
Это очень просто и много применений.
/usr/bin
может быть создана мягкая ссылка на ваш двоичный файл. Например, Python 2.7, Python 2.6 установлен, но / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6 Если вы находитесь в пути /usr/local/bin
и выполняет Python, он всегда выполняет Python 2.7. Указание .
примет исполняемый файл текущей папки.
.
- всегда представляет выполнение из текущего каталога. И ..
всегда означает, что выполняется из предыдущего каталога. Как указал Джордж в своем ответе, это поможет вам заметить, что вы выполняете файл в текущем рабочем каталоге (pwd
).
Я помню, как задавал этот вопрос своему старшему давным-давно, он сказал, что я должен добавить .
к моему пути, чтобы, когда я делаю a.out
, он просматривал текущий каталог и выполнял его. В этом случае мне не нужно делать ./a.out
.
Но лично я бы рекомендовал против этого. Со мной такого никогда не случалось, но если вы находитесь в инопланетном сетевом каталоге или чем-то подобном, и там существует вредоносный исполняемый файл с именем ls
, то иметь на своем пути .
- очень плохая идея. Не то чтобы вы сталкивались с этой проблемой очень часто, просто говоря.
В дополнение к другим ответам, здесь основная часть от man bash
, который объясняет что хорошо:
COMMAND EXECUTION After a command has been split into words, if it results in a simple command and an optional list of arguments, the following actions are taken. If the command name contains no slashes, the shell attempts to locate it. If there exists a shell function by that name, that function is invoked as described above in FUNCTIONS. If the name does not match a function, the shell searches for it in the list of shell builtins. If a match is found, that builtin is invoked. If the name is neither a shell function nor a builtin, and contains no slashes, bash searches each element of the PATH for a directory con‐ taining an executable file by that name.