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

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

99
задан 6 August 2015 в 21:48

11 ответов

Когда вы набираете название программы, например 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, но по причинам, указанным в связанном вопросе, я бы не рекомендовал его.

0
ответ дан 6 August 2015 в 21:48

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

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

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

0
ответ дан 6 August 2015 в 21:48
$ gcc hello.c -o /path/to/someplace/hello

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

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

0
ответ дан 6 August 2015 в 21:48

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

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

  • Когда Вы выполняете команду, или программа пытается сделать exec syscall (специальный метод Ядра, как программы запущены), система ищет файл путем прохождения через каждого из каталогов в ПУТИ. После того как программа была найдена, даже если это находится в нескольких каталогах, поиск прерван, и первый найденный выполняется.

Для петляния необходимо будет установить исполняемый бит в полномочиях:

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

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

    alt text

Можно теперь скопировать файл в любой из каталогов в ПУТИ, для наблюдения, которые там - и они установлены на основе в расчете на пользователя - тип 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.

16
ответ дан 6 August 2015 в 21:48

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

0
ответ дан 6 August 2015 в 21:48

Почему необходимо ввести ./ прежде, чем выполнить программу?

В терминале, каждый раз, когда Вы вводите имя приложения, скажем, 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

Примечание: изменение userName к Вашему фактическому имени пользователя Ubuntu.

Что, если у Вас есть другие программы, Вы хотите выполнить? И они - все в различных папках? Ну, "более организованное" решение состояло бы в том, чтобы создать названную папку 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, и Вы затем сможете выполнить его без ./ также.

Примечание: благодаря комментарию @Joe, когда Вы делаете резервные копии, символьные ссылки должны быть обработаны особенно. По умолчанию, rsync не обрабатывает их вообще, поэтому когда Вы восстанавливаете, они не там.

12
ответ дан 6 August 2015 в 21:48

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

0
ответ дан 6 August 2015 в 21:48

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

[root@server ~]#/path/to/file/file.pl

то же как:

[root@server file]#./file.pl

в предыдущем примере Вы прошли каталог и его каталоги глотка к расположению файла и использовали ". /" для петляния в текущем каталоге.

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

0
ответ дан 6 August 2015 в 21:48

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

  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. . - всегда представляет выполнение из текущего каталога. И .. всегда означает, что выполняется из предыдущего каталога.
0
ответ дан 6 August 2015 в 21:48

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

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

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

0
ответ дан 6 August 2015 в 21:48

В дополнение к другим ответам, здесь основная часть от 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.
1
ответ дан 11 October 2019 в 10:26

Другие вопросы по тегам:

Похожие вопросы: