Почему при выполнении программы на 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
.
Система просматривает эти каталоги в указанном порядке и, если не может найти, программа выдает команду не найдена
ошибка.
Добавление к команде ./
эффективно говорит: «Забудьте о PATH, я хочу, чтобы вы смотрели только в текущем каталоге».
Точно так же вы можете указать системе, чтобы она просматривала только другое конкретное местоположение, добавив к команде относительный или абсолютный путь, например:
../
означает в родительском каталоге, например, ../ hello
искать hello в родительском каталоге.
./ Debug / hello
: "найдите hello
в подкаталоге Debug моего текущего каталога."
или / bin / ls
: "найдите ls
в каталоге / bin
"
По умолчанию текущий каталог отсутствует в пути, поскольку это считается угрозой безопасности. См. Почему. не в пути по умолчанию? на Superuser, почему.
Можно добавить текущий каталог в ваш PATH, но по причинам, указанным в связанном вопросе, я бы не рекомендовал это.
Помимо других ответов,здесь основная часть из 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.
"./" означает, что вы хотите выполнить файл в текущем каталоге, это ярлык для ввода всего пути, например:
[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. Указание .
возьмет исполняемый файл текущей папки.
.
- всегда представляет выполнение из текущего каталога. И ..
всегда означает выполнение из предыдущего каталога. $ gcc hello.c -o /path/to/someplace/hello
создаст исполняемый файл в каком-то месте. Если это место находится на вашем пути, вы сможете запустить файл.Вы можете создать сценарий, если хотите создать метку для действия «Скомпилируйте этот исходный код с помощью gcc и поместите исполняемый файл в какое-нибудь место на вашем пути»
. Я бы посоветовал вам создать новый каталог под названием «testbin» или что-то в этом роде и поместите его на свой путь, чтобы ваши существующие каталоги пути были чистыми.
./
исключает ненужный поиск пути. ./
принудительный поиск только в текущем каталоге. Если мы не укажем ./
, тогда он будет искать различные пути, установленные в системе, например / usr / bin
, / usr / sbin /
и т. Д.
./
перед выполнением программы? В терминале, когда вы вводите имя приложения, скажем, gedit
, терминал будет искать в некоторых (заранее определенных) каталогах, содержащих приложения (двоичные файлы приложений). Имена этих каталогов содержатся в переменной с именем PATH
. Вы можете увидеть, что находится в этой переменной, выполнив echo $ PATH
. Видите эти каталоги, разделенные :
? Это каталоги, в которых терминал будет искать, если вы просто наберете gedit
, nautilus
или a.out
. Как видите, путь к вашей программе a.out
там отсутствует. Когда вы выполняете ./ a.out
, вы говорите терминалу «посмотрите в текущий каталог и запустите a.out
, и не заходите смотреть в ПУТЬ
.
Если вы не хотите каждый раз вводить ./
, вам нужно добавить каталог 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
их вообще не обрабатывает, поэтому при восстановлении их там нет.
'./' имеет смысл, когда вы запускаете программу, которая известна вам и специфична, например, ваша собственная. Эта программа должна присутствовать в Вашем текущем каталоге. A './' не имеет смысла, когда вы выполняете стандартную команду, которая находится где-то в $PATH. Команда "what command-to-run" сообщает вам, где находится команда-выполнение в $PATH.
Как указал Джордж в своем ответе, это поможет вам заметить, что ваш выполняющий файл в текущей рабочей директории (pwd
).
Я помню, как задавал этот вопрос моему старшему руководителю давным-давно, он сказал, что я должен добавить .
к моему пути, чтобы когда я сделаю a.out
, он посмотрел в текущий каталог и выполнил его. В этом случае я не должен делать ./a.out
.
Но лично я бы рекомендовал не делать этого. Со мной такого никогда не случалось, но если Вы находитесь в чужом сетевом каталоге или что-то в этом роде, и там существует вредоносный исполняемый файл под названием ls
, то иметь в своем пути .
- это очень плохая идея. Не то чтобы вы часто сталкивались с этой проблемой, просто скажите.
./
выполняет файлы, которые не находятся в вашем $PATH
, а выполняет файл в текущем каталоге (или другой через ./home/stefano/script.sh
). Теперь PATH - это переменная окружения, содержащая все места, где bash может искать исполняемые программы, не имея полного (абсолютного) пути к ним.
Это разделение необходимо, чтобы избежать запуска неправильного файла. Т.е. если у Вас в домашнем каталоге есть файл с именем ls
, его отсутствие в PATH не позволит bash перепутать его с настоящим ls
. Переменная PATH также определяет порядок поиска:
exec
(специальный метод ядра, как запускаются программы), система ищет файл, просматривая каждую из директорий в Вашем PATH. После того, как программа найдена, даже если она находится в нескольких каталогах, поиск прерывается и запускается первый найденный.Для запуска файла необходимо установить исполняемый бит в permissions:
Так как вы уже в командной строке, вы можете просто набрать chmod +x finename
.
Или вы можете установить права доступа, щелкнув правой кнопкой мыши по файлу и выбрав Свойства :
Теперь вы можете скопировать файл в любой из каталогов в PATH, чтобы посмотреть, какие из них там находятся - и они установлены для каждого пользователя - тип 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
. Вы можете узнать, где находятся ваши файлы, используя тип cat
и где находится cat
.
Причина проста.
Предположим, у вас есть команда с тем же именем, что и у приложения в текущем каталоге. Тогда выполнение команды в оболочке вызовет ваше приложение вместо встроенной команды. Это будет проблемой безопасности, если больше ничего не использовать.
Требуя использования ./
спереди, оболочка командной строки знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с таким именем.