При выполнении программы на 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, но по причинам, указанным в связанном вопросе, я бы не рекомендовал его.
Причина этого проста.
Предположим, у вас есть команда с тем же именем, что и у приложения в текущем каталоге. Затем выполнение команды в оболочке вызовет ваше приложение вместо встроенной команды. Это было бы проблемой безопасности, если ничего больше.
Требуя, чтобы ./
использовалось спереди, оболочка знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с этим именем.
./
выполняет файлы, которых нет в вашем $PATH
, скорее он выполняет файл в текущем каталоге (или другом через ./home/stefano/script.sh
). Теперь PATH - это переменная окружения, которая содержит все места, где bash может искать исполняемые программы, не имея полного (абсолютного) пути к ним.
Это разделение необходимо, чтобы избежать запуска неправильного файла. То есть если у вас есть файл с именем ls
в вашем домашнем каталоге, его нет в вашей переменной PATH, и bash не сможет спутать его с реальным ls
. Переменная PATH также определяет порядок поиска:
exec
(особый метод ядра, способ запуска программ), Система ищет файл, просматривая все каталоги в вашей переменной PATH. Как только программа найдена, даже если она находится в нескольких каталогах, поиск прерывается, и запускается первая найденная. Чтобы запустить файл, вам нужно установить исполняемый бит в разрешениях:
Поскольку вы уже находитесь в командной строке, вы можете просто ввести [ 117]. [+1123]
Или вы можете установить разрешения, щелкнув правой кнопкой мыши файл и выбрав Свойства :
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
.
Как указал Джордж в своем ответе, это поможет вам заметить, что вы выполняете файл в текущем рабочем каталоге (pwd
).
Я помню, как задавал этот вопрос своему старшему давным-давно, он сказал, что я должен добавить .
к моему пути, чтобы, когда я делаю a.out
, он просматривал текущий каталог и выполнял его. В этом случае мне не нужно делать ./a.out
.
Но лично я бы рекомендовал против этого. Со мной такого никогда не случалось, но если вы находитесь в инопланетном сетевом каталоге или чем-то подобном, и там существует вредоносный исполняемый файл с именем ls
, то иметь на своем пути .
- очень плохая идея. Не то чтобы вы сталкивались с этой проблемой очень часто, просто говоря.
$ gcc hello.c -o /path/to/someplace/hello
создаст исполняемый файл в некотором месте. Если это место находится на вашем пути, вы сможете запустить файл. Вы можете написать это, если хотите создать ярлык для действия «скомпилируйте этот исходный код с помощью gcc и поместите исполняемый файл в какое-то место, которое находится на вашем пути»
Я бы посоветовал вам создать новый каталог с именем "testbin" или что-то в этом роде и поместите его на свой путь, чтобы сохранить существующие каталоги путей чистыми.
«./» имеет смысл, когда вы запускаете программу, известную для вас и конкретную, например, свой собственный. Эта программа должна присутствовать в вашем текущем каталоге. «./» не имеет смысла, когда вы запускаете стандартную команду, которая находится где-то в $ PATH. Команда «какая команда запускается» сообщает вам, где находится команда запуска в $ PATH.
./
устраняет ненужный поиск пути. ./
заставляет искать только в текущем каталоге. Если мы не дадим ./
, он будет искать различные пути, заданные в системе, такие как /usr/bin
, /usr/sbin/
и т. Д.
«./» означает, что вы хотите выполнить файл в текущем каталоге, это ярлык для ввода полного пути, например:
[root@server ~]#/path/to/file/file.pl
такой же, как:
[root@server file]#./file.pl
[114 ] в предыдущем примере вы прошли через каталог и его подкаталоги к месту нахождения файла и использовали «./» для запуска файла в текущем каталоге.
тот, что перед ним, " [root @ server ~] # / path / to / file / file.pl " также выполнит файл, если вам лень "cd" пробиться к месту расположения файла .
./
перед выполнением программы? В терминале, всякий раз, когда вы вводите имя приложения, скажем, gedit
, терминал будет смотреть в некоторых ( предварительно определенные) каталоги, содержащие приложения (двоичные файлы приложений). Имена этих каталогов содержатся в переменной с именем PATH
. Вы можете увидеть, что находится в этой переменной, выполнив echo $PATH
. Видите эти каталоги, разделенные :
? Это каталоги, в которых терминал будет искать, если вы просто наберете gedit
, nautilus
или a.out
. Как видите, путь к вашей a.out
программе отсутствует. Когда вы делаете ./a.out
, вы говорите терминалу «посмотрите в текущую директорию и запустите a.out
, а не смотрите в PATH
.
./
каждый раз, вам нужно добавить каталог a.out
в $PATH
. В следующих инструкциях я предполагаю, что путь к a.out
равен [ 1117], но вы должны изменить его на свой фактический путь.
Просто добавьте следующую строку в конец файла ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
[ 1164] Источник: Постоянные переменные среды
Выйдите из системы и снова войдите в нее. Теперь вы сможете запустить [ 1119] без ./
из любого каталога.
Если у вас есть другие программы в других каталогах, вы можете просто добавить их в строку выше. Однако я бы посоветовал иметь один каталог с именем «myPrograms», например, и положить все ваши программы под него.
Примечание: изменить
blockquote>userName
на ваш фактический Имя пользователя Ubuntu.Что если у вас есть другие программы, которые вы хотите запустить? И они все в разных папках? Что ж, «более организованным» решением было бы создать папку с именем
bin
в вашем домашнем каталоге и добавить символические ссылки (ярлыки) в эту папку. Вот как:
mkdir /home/userName/bin
- Это создаст папку
bin
в вашей домашней директории.
ln -s /path/to/programs/a.out /home/userName/bin
- Это создаст «символическую ссылку» (в основном, ярлык) вашей программы
a.out
в разделеbin
. [ 1168]Выйдите из системы и снова войдите в систему. Теперь вы сможете запускать
a.out
без./
из любого каталога.Теперь, когда у вас есть другая программа где-нибудь еще, скажем, программа
b.in
на вашем рабочем столе, все, что вам нужно сделать, это:ln -s /home/userName/Desktop/b.in /home/userName/bin
, и вы сможете запустить ее без 1132].Примечание: благодаря @ комментарию Джо , когда вы делаете резервные копии, символические ссылки должны обрабатываться специально. По умолчанию
BLOCKQUOTE>rsync
их вообще не обрабатывает, поэтому при восстановлении их там нет.
Это очень просто и много применений.
/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. Указание .
примет исполняемый файл текущей папки.
.
- всегда представляет выполнение из текущего каталога. И ..
всегда означает, что выполняется из предыдущего каталога.
.
к ВашемуPATH
(как другие 2 ответа в настоящее время предполагают), из-за угрозы безопасности, упомянутой в этом ответе. – Guffa 16.07.2013, 20:20/home/user/foo/a.out
или./build/a.out
– alldayremix 17.07.2013, 01:57.
является особенным, потому что это означает " мой текущий directory" так мог быть любой каталог, в котором пользователь находит их сам с чтением и полномочиями на исполнение. Это потенциально более опасно, чем добавление определенного полностью определенного пути. – Reman 17.07.2013, 09:15.
не содержит особого статуса, it' s просто путь, который мог точно также запуститься с/
и./blah
, будет работать точно также сcat
илиgrep
как подсказка удара. – Peter Mortensen 17.07.2013, 09:26