it-swarm-ru.tech

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

Почему мы используем ./filename выполнить файл в linux?

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

89
Renjith G

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

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

80
badp

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

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

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

103
mattdm

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

$ ls

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

$ a.out

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

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

$ gcc test.c -o test
$ ./test
45
Simon Whitaker

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

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

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

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

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

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

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

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

4
tiktak

Более полное правило на самом деле: если в пути есть косая черта /, не ищите PATH

Прежде чем мы перейдем к обоснованию, вы должны сначала узнать об этом факте:

bin/someprog

или:

/bin/someprog

или:

cd bin
./myexec

выполнить bin/someprog без поиска в переменной PATH по той же самой причине: все bin/someprog, /bin/someprog и ./someprog имеют косую черту / в них.

Сам по себе someprog не имеет косой черты / и поэтому выполняет поиск только в PATH.

POSIX 7 определяет это правило по адресу: http: //pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

Обоснование правила / POSIX PATH

Предположим, что работает:

someprog

будет искать:

  • относительно CWD сначала
  • относительно PATH после

Затем, если вы хотите запустить /bin/someprog из вашего дистрибутива, и вы сделали:

someprog

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

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

Именно поэтому наличие относительных путей в вашем PATH - действительно плохая идея. Я смотрю на тебя, node_modules/bin .

И наоборот, предположим, что работает:

./someprog

Будет искать:

  • по отношению к PATH первым
  • относительно CWD после

Затем, если вы просто загрузили скрипт someprog из репозитория git и хотели запустить его из CWD, вы никогда не были бы уверены, что это именно та программа, которая будет работать, потому что, возможно, ваш дистрибутив имеет:

/bin/someprog

который находится в вашем ПУТИ из какого-то пакета, который вы установили после того, как выпили слишком много после Рождества в прошлом году.

Поэтому, опять же, вы будете вынуждены всегда запускать локальные сценарии относительно CWD с полными путями, чтобы знать, что вы запускаете:

"$(pwd)/someprog"

что было бы крайне раздражающим.

Другое правило, которое вы могли бы соблазнить, было бы:

относительные пути используют только PATH, абсолютные пути только CWD

но опять-таки это заставляет пользователей всегда использовать абсолютные пути для сценариев, не относящихся к PATH, с "$(pwd)/someprog".

Правило поиска пути / предлагает простое для запоминания решение проблемы about:

  • косая черта: не используйте PATH
  • без косой черты: используйте только PATH

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

Иногда немного раздражает, что вы не можете найти some/prog относительно PATH, но я не вижу более разумного решения этого.