При выполнении программы на C a.out
, используя терминал Ubuntu, почему мне всегда нужно печатать ./
раньше a.out
, а не просто писать a.out
? Есть ли решение для этого?
При выполнении программы на 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
"
По умолчанию текущий каталог не находится в пути, поскольку считается угрозой безопасности. Посмотрите, почему. не в пути по умолчанию? на суперпользователя почему.
Можно добавить текущий каталог в вашу переменную PATH, но по причинам, указанным в связанном вопросе, я бы не рекомендовал это делать.
.
к себе PATH
(как предлагают другие 2 ответа) из-за угрозы безопасности, упомянутой в этом ответе.
.
, вы можете использовать полный или относительный путь к исполняемому файлу, например, /home/user/foo/a.out
или./build/a.out
.
он особенный, потому что он означает «мой текущий каталог», поэтому он может быть любым каталогом, в котором пользователь находит себя с привилегиями чтения и выполнения. Это потенциально более опасно, чем добавление определенного полного пути.
.
не имеет особого статуса, это просто путь, с которого можно начинать, /
и он ./blah
будет работать так же хорошо с cat
или grep
как приглашение bash.
Причина этого проста.
Предположим, у вас есть команда с тем же именем, что и приложение в текущем каталоге. Затем выполнение команды в оболочке вызовет ваше приложение вместо встроенной команды. Это было бы проблемой безопасности, если ничего больше.
Требуя ./
использования спереди, оболочка знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с этим именем.
./
выполняет файлы, которых нет в вашем $PATH
, скорее он выполняет файл в текущем каталоге (или другом через ./home/stefano/script.sh
). Теперь PATH - это переменная окружения, которая содержит все места, где bash может искать исполняемые программы, не имея полного (абсолютного) пути к ним.
Это разделение необходимо, чтобы избежать запуска неправильного файла. То есть, если у вас есть файл, который называется ls
в вашем домашнем каталоге, он не будет находиться в вашей переменной PATH, чтобы bash не перепутал его с реальным ls
. Переменная PATH также определяет порядок поиска:
exec
системный вызов (особый метод ядра, способ запуска программ), система ищет файл, просматривая каждый из каталогов в вашей переменной PATH. Как только программа найдена, даже если она находится в нескольких каталогах, поиск прерывается, и запускается первая найденная программа.Чтобы запустить файл, вам нужно установить исполняемый бит в разрешениях:
Поскольку вы уже в командной строке, вы можете просто набрать 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
. Вы можете узнать, где находятся ваши файлы, используя type cat
и whereis cat
.
gcc
, что автоматически устанавливает бит выполнения.
./
перед выполнением программы?В терминале всякий раз, когда вы вводите имя приложения, скажем 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
и тогда вы будете иметь возможность запускать его без , ./
а также.
Примечание: благодаря комментарию @ Джо , когда вы делаете резервные копии, символические ссылки должны обрабатываться специально. По умолчанию они
rsync
вообще не обрабатываются, поэтому при восстановлении их там нет.
Как указал Джордж в своем ответе, это поможет вам заметить, что вы выполняете файл в текущем рабочем каталоге ( pwd
).
Я не забываю задавать этот вопрос своему старшему давным-давно, он сказал, что я должен добавить .
к своему пути, чтобы, когда я делаю, a.out
он смотрел в текущем каталоге и выполнял это. В этом случае мне не нужно делать ./a.out
.
Но лично я бы рекомендовал против этого. Это никогда не случалось со мной, но если вы находитесь в инопланетном сетевом каталоге или чем-то подобном, и там существует вредоносный исполняемый файл с именем ls
, то иметь .
на своем пути - очень плохая идея. Не то чтобы вы сталкивались с этой проблемой очень часто, просто говоря.
.
в $PATH
. Очень опасная идея.
В дополнение к другим ответам, вот основная часть, из man bash
которой хорошо это объясняется:
КОМАНДНОЕ ИСПОЛНЕНИЕ После того, как команда была разбита на слова, если это приводит к простому команда и необязательный список аргументов, следующие действия приняты. Если имя команды не содержит косых черт, оболочка пытается найти Это. Если существует функция оболочки с таким именем, эта функция вызывается, как описано выше в FUNCTIONS. Если имя не соответствует функция, оболочка ищет его в списке встроенных функций оболочки. Если найдено совпадение, которое встроено. Если имя не является ни функцией оболочки, ни встроенным, и не содержит косая черта, bash ищет каждый элемент PATH для поиска присвоение исполняемого файла по этому имени.
«./» имеет смысл, когда вы запускаете программу, которая вам известна и конкретна, например, ваша собственная. Эта программа должна присутствовать в вашем текущем каталоге. «./» не имеет смысла, когда вы запускаете стандартную команду, которая находится где-то в $ PATH. Команда «какая команда запускается» сообщает вам, где находится команда запуска в $ PATH.
$ gcc hello.c -o /path/to/someplace/hello
создаст исполняемый файл в каком-то месте. Если это место находится на вашем пути, вы сможете запустить файл. Вы можете написать это, если хотите создать метку для действия «скомпилируйте этот исходный код, используя gcc, и поместите исполняемый файл в какое-то место на вашем пути»
Я бы посоветовал вам создать новый каталог с именем «testbin» или что-то в этом роде и поместить его в свой путь, чтобы сохранить существующие каталоги путей чистыми.
./
устраняет ненужный поиск пути. ./
заставить искать только в текущем каталоге. Если мы не дадим, ./
он будет искать различные пути, заданные в системе, например /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. Указание .
займет исполняемый файл текущей папки.
.
- всегда представляет выполнение из текущего каталога. И ..
всегда означает, что выполняется из предыдущего каталога.