Во время выполнения программы на языке Си, a.out, используя терминал Ubuntu, почему мне всегда нужно вводить ./ до a.out, вместо того , чтобы просто писать a.out? Есть ли решение для этого?
Когда вы вводите название программы, например a.out система ищет файл по вашему ПУТИ. В моей системе ПУТЬ установлен на
/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 ошибка.
Добавление команды с помощью ./ эффективно говорит: "забудьте о ПУТИ, я хочу, чтобы вы искали только в текущем каталоге".
Аналогичным образом вы можете указать системе искать только в другом определенном местоположении, добавив к команде относительный или абсолютный путь, например:
../ означает в родительском каталоге, например ../hello найдите hello в родительском каталоге.
./Debug/hello : "ищите hello в подкаталоге Debug моего текущего каталога."
или /bin/ls : "ищите ls в каталоге /bin"
По умолчанию текущий каталог отсутствует в пути, поскольку он считается угрозой безопасности. Видеть Почему. не в пути по умолчанию? на суперпользователя, почему.
Можно добавить текущий каталог в свой ПУТЬ, но по причинам, указанным в связанном вопросе, я бы не рекомендовал этого делать.
Причина этого проста.
Предположим, у вас есть команда с тем же именем, что и приложение в текущем каталоге. Затем выполнение команды в командной оболочке вызовет ваше приложение вместо из встроенной команды. Это было бы проблемой безопасности, если не чем иным.
Требуя ./ для использования спереди оболочка знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с этим именем.
./ выполняет файлы, которых нет в вашем $PATH, скорее он выполняет файл в текущем каталоге (или другом через ./home/stefano/script.sh). Теперь PATH - это переменная окружения, которая содержит все места, где bash может искать исполняемые программы, не имея полного (абсолютного) пути к ним.
Это разделение необходимо, чтобы избежать запуска неправильного файла. Т.е. если у вас есть файл с именем ls в вашем домашнем каталоге, если он не находится на вашем ПУТИ, bash не сможет спутать его с реальным ls. Переменная PATH также определяет порядок поиска:
- Когда вы выполняете команду или программа пытается выполнить
execсистемный вызов (специальный метод Ядра, как запускаются программы), система ищет файл, просматривая каждый из каталогов в вашем ПУТИ. Как только программа найдена, даже если она находится в нескольких каталогах, поиск прерывается и запускается первый найденный каталог.
Чтобы запустить файл, вам нужно будет установить исполняемый бит в разрешениях:
Поскольку вы уже находитесь в командной строке, вы можете просто ввести
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.
Зачем вам нужно печатать ./ перед выполнением программы?
В терминале всякий раз, когда вы вводите имя приложения, скажем gedit, терминал будет искать в некоторых (предопределенных) каталогах, содержащих приложения (двоичные файлы приложений). Имена этих каталогов содержатся в переменной, называемой PATH. Вы можете увидеть, что находится в этой переменной, выполнив echo $PATH. Смотрите эти каталоги, разделенные :? Это каталоги, в которых терминал будет выполнять поиск, если вы просто наберете gedit, nautilus, или a.out. Как вы можете видеть, путь вашего a.out программы там нет. Когда вы это сделаете ./a.out, вы говорите терминалу "посмотрите в текущем каталоге и запустите a.out, и не ходи заглядывать в PATH.
Решение 1
Если вы не хотите вводить ./ каждый раз вам нужно будет добавлять a.outкаталог в $PATH. В следующих инструкциях я предположу, что путь к a.out является /path/to/programs/, но вы должны изменить его на свой фактический путь.
Просто добавьте следующую строку в конец файла
~/.pam_environment:PATH DEFAULT=${PATH}:/path/to/programsИсточник: Постоянные переменные среды
Выйдите из системы и снова войдите в систему. Теперь вы сможете запускать
a.outбез./из любого каталога.
Если у вас есть другие программы в других каталогах, вы можете просто добавить их в приведенную выше строку. Однако я бы посоветовал, например, иметь один каталог под названием "myPrograms" и поместить в него все ваши программы.
Решение 2
Примечание: менять
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's, когда вы делаете резервные копии, символические ссылки должны обрабатываться особым образом. По умолчанию,
rsyncне обрабатывает их вообще, поэтому, когда вы восстанавливаете, их там нет.
Как отметил Джордж в своем ответе, это поможет вам отметить, что ваш проведение файл в текущем рабочем каталоге (pwd).
Я помню, как давным-давно задавал этот вопрос своему старшему, он сказал, что я должен добавить . на мой путь, чтобы, когда я сделаю a.out он просматривает текущий каталог и выполняет его. В этом случае мне не нужно делать ./a.out.
Но лично я бы не рекомендовал этого делать. Со мной этого никогда не случалось, но если вы находитесь в чужом сетевом каталоге или что-то в этом роде, и вредоносный исполняемый файл называется ls существует там, то, имея . на вашем пути - это очень плохая идея. Не то чтобы вы очень часто сталкивались с этой проблемой, просто говорю.
В дополнение к другим ответам, вот существенная часть из man bash что хорошо объясняет это:
ВЫПОЛНЕНИЕ КОМАНДЫ После разделения команды на слова, если в результате получается простая команда и необязательный список аргументов, выполняются следующие действия. Если имя команды не содержит косых черт, оболочка попытается найти ее. Если существует функция оболочки с таким именем, эта функция вызывается, как описано выше в разделе ФУНКЦИИ. Если имя не соответствует функции, оболочка ищет ее в списке встроенных функций оболочки. Если найдено совпадение, вызывается этот встроенный компонент. Если имя не является ни функцией оболочки, ни встроенным и не содержит косых черт, bash ищет в каждом элементе ПУТИ каталог, содержащий исполняемый файл с таким именем.
'./' имеет смысл, когда вы запускаете программу, которая известна вам и специфична, например, вашу собственную. Эта программа должна присутствовать в вашем текущем каталоге. './' не имеет смысла, когда вы выполняете стандартную команду, которая находится где-то в $PATH.Команда "какая команда для запуска" сообщает вам, где находится команда для запуска в $PATH.
$ gcc hello.c -o /path/to/someplace/helloсоздаст исполняемый файл в некотором месте. Если это местоположение находится на вашем пути, вы сможете запустить файл. Вы можете написать это в скрипте, если хотите создать метку для действия "скомпилируйте этот исходный код с помощью gcc и поместите исполняемый файл в какое-нибудь место, которое находится на вашем пути".
Я бы посоветовал вам создать новый каталог с именем "testbin" или что-то в этом роде и поместить его в свой путь, чтобы сохранить существующие каталоги path чистыми.
./ устраняет ненужный поиск пути. ./ принудительный поиск только в текущем каталоге. Если мы не дадим ./ затем он будет искать различные пути, установленные в системе, например /usr/bin, /usr/sbin/ и т.д.
"./" означает, что вы хотите запустить файл в текущем каталоге, это ярлык для ввода полного пути, например:
[root@server ~]#/path/to/file/file.plэто то же самое, что и :
[root@server file]#./file.plв предыдущем примере вы прошли через каталог и его вспомогательные каталоги к местоположению файла и использовали "./" для запуска файла в текущем каталоге.
тот, что был до этого "[root@server ~]#/path/to/file/file.pl" также выполнит файл, если вы нажмете на "cd" свой путь к местоположению файла.
Связанный вопрос в Unix.SE Почему мы используем косую черту “./” для выполнения файла?