Почему мне нужно вводить «./» перед выполнением программы в текущем каталоге?

87

При выполнении программы C a.out , используя терминал Ubuntu, почему мне всегда нужно набирать ./ до a.out вместо того, чтобы просто писать a.out ? Есть ли решение для этого?

    
задан Prashant Chikhalkar 16.07.2013 в 13:58
источник

10 ответов

114

При вводе имени программы, например 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 искать hello в родительском каталоге.

./Debug/hello : "найдите hello в подкаталоге Debug моего текущего каталога."

или /bin/ls : "найдите ls в каталоге /bin "

По умолчанию текущий каталог не находится в пути, поскольку считается риском безопасности. См. Почему. а не по пути по умолчанию? на Superuser для чего.

Можно добавить текущий каталог в PATH, но по причинам, указанным в связанном вопросе, я бы не рекомендовал его.

    
ответ дан Warren Hill 16.07.2013 в 15:20
источник
24

Причина этого проста.

Предположим, что у вас есть команда с тем же именем, что и приложение в текущем каталоге. Затем запуск команды в оболочке вызовет ваше приложение вместо встроенной команды. Это будет проблемой безопасности, если ничего другого.

Если требуется использовать ./ в начале, оболочка знает, что вы хотите выполнить приложение с заданным именем, а не встроенную команду с этим именем.

    
ответ дан Nathan Osman 16.12.2010 в 04:21
16

./ выполняет файлы, которые не находятся в вашем $PATH , скорее он выполняет файл в текущем каталоге (или другом через ./home/stefano/script.sh ). Теперь PATH - это переменная среды, которая содержит все места, где bash может искать исполняемые программы, не имея полного (абсолютного) пути к ним.

Это разделение необходимо, чтобы избежать неправильного файла. То есть если у вас есть файл с именем ls в вашем домашнем каталоге, то он не находится в вашем PATH, чтобы он не путал его с реальным ls . Переменная PATH также определяет порядок поиска:

  • Когда вы запустите команду или программа попытается сделать syscall exec (специальный метод ядра, как запускаются программы), система ищет файл, просматривая каждую из каталогов в вашей PATH , После того, как программа была найдена, даже если она находится в нескольких каталогах, поиск прерывается и первый из них запускается.

Чтобы запустить файл, вам нужно будет установить исполняемый бит в разрешениях:

  • Поскольку вы уже находитесь в командной строке, вы можете просто набрать chmod +x finename .

  • Или вы можете установить разрешения, щелкнув правой кнопкой мыши файл и выбрав Свойства :

Теперь вы можете скопировать файл в любой из каталогов в PATH, чтобы увидеть, какие из них находятся там - и они настроены для каждого пользователя - введите echo $PATH .

[email protected]:~$ 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 .

    
ответ дан Stefano Palazzo 16.12.2010 в 04:18
11

Зачем вам нужно вводить ./ перед выполнением программы?

В терминале каждый раз, когда вы вводите имя приложения, скажем, gedit , терминал будет выглядеть в некоторых (заранее определенных) каталогах, содержащих приложения (двоичные файлы приложений). Имена этих каталогов содержатся в переменной, называемой PATH . Вы можете увидеть, что находится в этой переменной, выполнив echo $PATH . См. Эти каталоги, разделенные : ? Это каталоги, в которые терминал будет искать поиск, если вы просто наберете gedit , nautilus или a.out . Как вы можете видеть, путь вашей a.out не существует. Когда вы делаете ./a.out , вы говорите терминалу "смотрите в текущем каталоге и запускаете a.out и не смотрите в PATH .

Решение 1

Если вы не хотите набирать ./ каждый раз, вам нужно добавить каталог a.out в $PATH . В следующих инструкциях я предполагаю, что путь к a.out равен /path/to/programs/ , но вы должны изменить его на ваш фактический путь.

  1. Просто добавьте следующую строку в конец файла ~/.pam_environment :

    PATH DEFAULT=${PATH}:/path/to/programs
    

    Источник: Постоянные переменные среды

  2. Выйдите из системы и войдите в систему. Теперь вы можете запустить a.out без ./ из любого каталога.

Если у вас есть другие программы в других каталогах, вы можете просто добавить их в указанную выше строку. Тем не менее, я бы посоветовал, например, иметь один каталог под названием "myPrograms" и поместить в него все ваши программы.

Решение 2

Note: change userName to your actual Ubuntu username.

Что делать, если у вас есть другие программы, которые вы хотите запустить? И все они в разных папках? Ну, "более организованным" решением было бы создать папку под названием " bin " в вашем домашнем каталоге и добавить символические ссылки (ярлыки) под этой папкой. Вот как это сделать:

  1. mkdir /home/userName/bin

    • Это создаст папку bin в вашем домашнем каталоге.
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • Это создаст "символическую ссылку" (в основном, ярлык) вашей программы a.out в разделе bin .
  3. Выйдите из системы и войдите в систему. Теперь вы можете запустить a.out без ./ из любого каталога.

Теперь, когда у вас есть другая программа в другом месте, скажем, программа b.in на вашем рабочем столе, вам нужно всего лишь: ln -s /home/userName/Desktop/b.in /home/userName/bin , и тогда вы сможете запустить ее без ./ as хорошо.

Note: thanks to @Joe's comment, when you do backups, symbolic links have to be handled specially. By default, rsync doesn't process them at all, so when you restore, they're not there.

    
ответ дан Alaa Ali 16.07.2013 в 15:27
1

Как отметил Джордж в своем ответе, это поможет вам заметить, что ваш исполняющий файл в текущем рабочем каталоге ( pwd ).

Я помню, как давно задавал этот вопрос моему старшему, он сказал, что я должен добавить . к своему пути, чтобы, когда я делаю a.out , он выглядит в текущем каталоге и выполняет это. В этом случае мне не нужно делать ./a.out .

Но, лично, я бы рекомендовал против этого. Это никогда не случалось со мной, но если вы находитесь в чужой сетевой директории или что-то еще, и существует вредоносный исполняемый файл с именем ls , то наличие . в вашем пути - очень плохая идея. Не то чтобы вы часто сталкивались с этой проблемой, просто говоря.

    
ответ дан Shrikant Sharat 16.12.2010 в 04:32
0

A './' имеет смысл, когда вы запускаете известную вам программу и, например, ваш собственный. Эта программа должна присутствовать в вашем текущем каталоге. A './' не имеет смысла, когда вы запускаете стандартную команду, которая находится где-то в $ PATH. Команда «какая команда для запуска» сообщает вам, где команда запуска находится в $ PATH.

    
ответ дан user7346 16.12.2010 в 12:06
0
$ gcc hello.c -o /path/to/someplace/hello

создаст исполняемый файл в определенном месте. Если это местоположение находится на вашем пути, вы сможете запустить файл. Вы можете создать сценарий, если хотите создать ярлык для действия «скомпилируйте этот исходный код с помощью gcc и поместите исполняемый файл в определенное место на вашем пути»

Я бы предложил вам создать новый каталог с именем testbin или что-то в этом роде и поместить его на свой путь, чтобы сохранить существующие каталоги путей.     

ответ дан Jon Kiparsky 16.07.2013 в 20:35
0

./ устраняет ненужный поиск пути. ./ принудительно выполнять поиск только в текущем каталоге. Если мы не дадим ./ , тогда он будет искать различные пути в системе, такие как /usr/bin , /usr/sbin/ и т. Д.

    
ответ дан user175959 17.07.2013 в 13:11
0

"./" означает, что вы хотите выполнить файл в текущем каталоге, его ярлык для ввода всего пути, например:

[[email protected] ~]#/path/to/file/file.pl

совпадает с:

[[email protected] file]#./file.pl

в предыдущем примере вы просмотрели каталог и его вспомогательные каталоги в папку файла и использовали «./» для запуска файла в текущем каталоге.

тот, который перед ним " [root @ server ~] # / path / to / file / file.pl " также выполнит файл, если вы ленитесь на «cd» свой путь к файлу местоположение и др.

    
ответ дан Khaled Moustafa 25.04.2014 в 02:20
-4

Это очень просто и имеет много применений.

  1. Если установлено несколько версий одного и того же приложения, оно будет доступно по другому пути, но в /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. Задание . займет исполняемый файл текущей папки.

  1. . - всегда представляет выполнение из текущего каталога. И .. всегда означает выполнение из предыдущего каталога.
ответ дан Ramjee Anna 17.07.2013 в 11:12