Почему мы используем «./» для выполнения файла?

84

Почему мы используем ./filenameдля запуска файла в Linux?

Почему бы просто не ввести его, как другие команды gccи lsт.д ...

Renjith G
источник
Разве первая строка не будет лучше написана как «Почему мы используем ./command_nameдля выполнения команды в Linux?»

Ответы:

78

В Linux, UNIX и связанных операционных системах .обозначает текущий каталог. Поскольку вы хотите запустить файл в вашем текущем каталоге, а этот каталог не в вашем $PATH, вам нужен ./бит, чтобы указать оболочке, где находится исполняемый файл. Итак, ./fooозначает запустить исполняемый файл, fooкоторый находится в этом каталоге.

Вы можете использовать typeили, whichчтобы получить полный путь любых команд, найденных в вашем $PATH.

badp
источник
5
Очень распространено выполнение программ в текущем каталоге. Почему оболочка тоже не ищет там? Сначала выполняется поиск в., Затем в $ PATH.
Майкл
Есть и другие, aliasкоторые могут мешать, а не только $PATH.
user2485710
18
@ Безопасность и здравый смысл Михаэля: если поиск выполняется .первым, то это будет проблема безопасности, которую вы или кто-то другой можете заменить, lsнапример (простой вирус / троянский файл: создайте zip-файл с именем исполняемого файла ls, когда кто-то просматривает , они запускают этот исполняемый файл, что ...). Если поиск производился в .последний раз, вы можете потратить немало времени на то, чтобы не знать, почему ваша программа не работает (например, вы создаете программу под названием test, вместо того, чтобы запускать ее, она запускает программу системного тестирования.
ctrl-alt-delor
Это также гарантирует, что если приложение или скрипт появляются несколько раз на вашем пути, вы выполняете версию, которую вы намереваетесь запустить (ту, которая находится прямо здесь, в вашей директории ".").
Jim2B
Вы можете выполнить export PATH="$PATH:."команду в текущем каталоге, если она не найдена в другом месте в PATH, вы можете добавить ее в свой файл .bashrc
jcubic,
99

Буквальный ответ такой же, как и у других: текущий каталог не в вашем $PATH.

Но почему? Короче говоря, это для безопасности. Если вы заглядываете в чей-то домашний каталог (или / tmp) и вводите просто gccили ls, вы хотите знать, что вы используете реальную, а не вредоносную версию, написанную вашим другом-шутником, которая стирает все ваши файлы. Другим примером может быть testили [, который может переопределить эти команды в сценариях оболочки, если ваша оболочка не имеет таких встроенных модулей.

Имея в .качестве последней записи в вашем пути немного безопаснее, но есть и другие атаки , которые используют это. Легко использовать обычные опечатки, такие как slили ls-l. Или найдите обычную команду, которая, как оказалось, не установлена ​​в этой системе - vimнапример, поскольку системные администраторы имеют вероятность набрать ее выше среднего.

mattdm
источник
5
Практический пример того, как кому-то это нравится
mattdm
Просто есть абсолютные пути в PATHпеременной среды.
Эд Хил
45

Если вы имеете в виду, зачем вам нужно ./ в начале - потому что (в отличие от Windows) текущий каталог по умолчанию не является частью вашего пути. Если вы запускаете:

$ ls

ваша оболочка ищет lsв каталогах переменную среды PATH ( echo $PATHчтобы увидеть ее) и запускает первый исполняемый файл, lsкоторый он находит. Если вы введете:

$ a.out

оболочка будет работать аналогично - но, вероятно, не найдет исполняемый файл с именем a.out. Вы должны указать оболочке, где находится a.out - если он находится в текущем каталоге (.), То путь будет ./a.out.

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

$ gcc test.c -o test
$ ./test
Саймон Уитакер
источник
Спасибо. Я сомневаюсь, зачем тебе это нужно ./ на старте .... Я использовал "." (чтобы определить текущую директорию), но почему после этого "/"?
Renjith G
8
/ является разделителем пути в Linux, поэтому вы используете его для отделения каталога (.) от имени файла (a.out). Без этого у вас есть .a.out, который сам по себе является допустимым именем файла. (Попробуйте touch .a.out; ls -lAэто увидеть.)
Саймон Уитакер
5
это то, как вы указываете путь в Unix, <dir>/<file>так что вы в основном говорите «выполнить файл в текущем каталоге», что обозначено./test
Rohan Monga
Редакция Red Hat Linux 9 (Shrike) 2.4.20-8 на i686 [renjithg @ cvsserver renjithg] $ touch .a.out; ls -lA всего 3 -rw-rw-r-- 1 renjithg renjithg 0 30 ноября 13 : 46 .a.out -rwxrwxr-x 1 renjithg renjithg 11669 30 ноября 13:46 a.out -rw-rw-r-- 1 renjithg renjithg 218 24 августа 2009 г. aray.c [renjithg @ cvsserver renjithg] $
Ренджит G
3
Red Hat Linux 9? Время обновить!
Mattdm
4

Вы можете попытаться добавить :.к своей переменной $ PATH.

Попробуйте ALT + F2 и наберите: gksudo gedit /etc/environmentесли вы используете Linux / GTK (это то, что вы имеете, если используете Ubuntu).

ОДНАКО, я настоятельно советую вам НЕ делать этого. Это плохо, плохо, плохо и плохо.

Вы знаете, что такие вещи работают так с 1970 года. Есть причина, по которой текущий каталог не включен в $ PATH.

. текущий каталог

.somethingбудет скрытым файлом (введите «ALT +», чтобы они появились в Nautilus, или попробуйте « ls -la».

./someProgram.sh это то, что вы вводите для запуска исполняемого файла someProgram.sh в текущем каталоге.

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

TikTak
источник