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

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

92
задан 06.08.2015, 21:48

10 ответов

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

119
ответ дан 11.10.2019, 10:26
  • 1
    Это. +1 не Делают , добавляют . к Вашему PATH (как другие 2 ответа в настоящее время предполагают), из-за угрозы безопасности, упомянутой в этом ответе. – Guffa 16.07.2013, 20:20
  • 2
    Может также стоить отметить, что нет ничего специального [приблизительно 110] здесь, можно использовать полный или относительный путь для исполняемого файла, например, /home/user/foo/a.out или ./build/a.out – alldayremix 17.07.2013, 01:57
  • 3
    @tobyodavies; На самом деле . является особенным, потому что это означает " мой текущий directory" так мог быть любой каталог, в котором пользователь находит их сам с чтением и полномочиями на исполнение. Это потенциально более опасно, чем добавление определенного полностью определенного пути. – Reman 17.07.2013, 09:15
  • 4
    @WarrenHill при рассмотрении добавления его к пути, да это очень отличается. Однако с точки зрения синтаксиса удара, . не содержит особого статуса, it' s просто путь, который мог точно также запуститься с / и ./blah, будет работать точно также с cat или grep как подсказка удара. – Peter Mortensen 17.07.2013, 09:26
  • 5
    @tobyodavies: хорошо I' ve отредактировал мой ответ для включения точки. – AdmiralAdama 18.07.2013, 08:56

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

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

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

24
ответ дан 11.10.2019, 10:26
  • 1
    Спасибо George. Спасибо имеет смысл (и я думаю, что слышал, что несколько лет назад - должны придерживаться Linux достаточно долго на этот раз для этого материала для впитываний), – srccode 16.12.2010, 15:28
  • 2
    Ваше объяснение вводит в заблуждение, существует различие между встроенными командами в оболочке и исполняемых файлах, которые доступны через переменную ПУТИ. На самом деле, Ваш ответ больше я читал, это чувствует себя более неправильным. – Guffa 25.09.2015, 03:17

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

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

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

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

  • Поскольку вы уже находитесь в командной строке, вы можете просто ввести [ 117]. [+1123]

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

    alt text

    [1125]
[1126 ] Теперь вы можете скопировать файл в любой из каталогов в 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.

16
ответ дан 11.10.2019, 10:26

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

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

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

1
ответ дан 11.10.2019, 10:26
  • 1
    хорошо, Stefano принял свой ответ для содержания этой информации:) – Peter Mortensen 16.12.2010, 05:34
  • 2
    Я полностью согласен с не добавлением . к $PATH. Очень опасная идея. – John Conde 16.12.2010, 05:37
$ gcc hello.c -o /path/to/someplace/hello

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

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

0
ответ дан 11.10.2019, 10:26

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

0
ответ дан 11.10.2019, 10:26

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

0
ответ дан 11.10.2019, 10:26

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

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

такой же, как:

[root@server file]#./file.pl
[114 ] в предыдущем примере вы прошли через каталог и его подкаталоги к месту нахождения файла и использовали «./» для запуска файла в текущем каталоге.

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

0
ответ дан 11.10.2019, 10:26

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

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

Решение 1

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

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

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

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

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

Если у вас есть другие программы в других каталогах, вы можете просто добавить их в строку выше. Однако я бы посоветовал иметь один каталог с именем «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. [ 1168]
  3. Выйдите из системы и снова войдите в систему. Теперь вы сможете запускать a.out без ./ из любого каталога.

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

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

12
ответ дан 11.10.2019, 10:26

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

  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. . - всегда представляет выполнение из текущего каталога. И .. всегда означает, что выполняется из предыдущего каталога.
-4
ответ дан 11.10.2019, 10:26

Теги

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