В чем разница между запуском исполняемого файла только по имени и добавлением точки / косой черты перед ним?


13

Это вывод ls -allкоманды:

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

Теперь, когда я просто запускаю, jdevон запускает другую версию Oracle JDveloper, чем когда я запускаю его как .. ./jdevПочему это так?

Ответы:


20

Когда вы запускаете исполняемый файл (точнее, в мире unix / linux - файл с исполняемыми правами / флагом), примерно так:

$ ./jdev

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

(см. права доступа к файлам в linux / unix )

Когда вы запускаете его как

$ jdev

тогда, скорее всего, там jdevгде-то установлен в системе, и у вас есть в $PATH(например, /usr/bin/или /bin/или /usr/local/bin/)

Как сказал Петерф : вы можете использовать whichдля указания исполняемого файла, который запускается с помощью определенной команды, например:

$ which find
/usr/bin/find

1
Также не то, что whichутилита может сказать вам, какой исполняемый файл будет использоваться, если путь не указан.
Петер

@peterph Отредактировал мой ответ.
Патрик

7
Гораздо лучше использовать, typeчтобы проверить, что запускается определенной командой. Cause whichпокажет вам просто двоичный файл где-то в $ PATH, однако он может быть связан с абсолютно другим двоичным файлом.
Раш

@rush Я только что попробовал это, и это не будет работать, как вы говорите [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Покаzsoelim -> soelim
Патрик

2
@Patryk Я думаю, что rush подразумевал псевдонимы / функции оболочки, которые whichне имеет возможности найти, поскольку это автономный двоичный файл, не имеющий доступа к работающей среде оболочки (под которой я имею в виду псевдонимы и функции, а не только переменные среды). некоторые из которых передаются по наследству).
Петер

8

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

Если в имени есть косая черта, то этого не происходит, имя берется как путь для выполнения команды (хотя некоторые оболочки, например, zshпозволяют псевдонимам или функциям иметь косую черту в имени, которая затем будет иметь приоритет).

Итак, если вы хотите запустить команду с именем, fooкоторая находится в текущем рабочем каталоге, вам нужно придумать имя, которое содержит косую черту. ./fooявляется наиболее очевидным. Вы также можете использовать полный путь, или ../dir/foo...

Чтобы узнать, какая оболочка будет работать, используйте typeкоманду. Не используйте whichкоманду, которая обычно не делает то, что, как вы думаете, она делает, и является наследием, от cshкоторого лучше оставить в покое.


Почему не «какой», а «тип»?
Компьютерщик

@ Geek, это часто задаваемые вопросы здесь, см. Unix.stackexchange.com/search?q=[which]+type
Стефан

Вы предоставили правильную ссылку?
Компьютерщик

Это результат поиска на этом сайте, чтобы доказать, что это часто задаваемый вопрос. Многие ответы на эти вопросы скажут вам, почему бы не использовать which. См., Например, unix.stackexchange.com/questions/16693/…
Стефан

2

Я рекомендую использовать встроенную в Zsh 'where' (лучше, чем 'which'), чтобы увидеть, как и в каком порядке будут найдены псевдонимы, встроенные оболочки или что-то еще для $ PATH ;-)

Вот пример, чтобы лучше понять вещи, как они выбраны:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %

1

Хотя это, вероятно, зависит от вашей оболочки, правило обычно таково:

  • Если вы указываете путь, относительный или абсолютный, этот путь используется. ./jdevявляется относительным путем, потому что .обозначает текущий каталог (на самом деле, ls -all .даст вам так же, как ls -all). Если вы делаете /usr/bin/tool/, вы используете абсолютный путь. В этих случаях исполняемый файл указывается.

  • Если вы не указали путь, а просто имя, в каталогах $PATHищется инструмент, который вы пытаетесь запустить.

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

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

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


Ваша терминология сбивает с толку. jdevодин также относительный путь. Правило таково: если он не содержит косую черту, то он ищется в псевдонимах, функциях и $PATH, в противном случае, он просматривается непосредственно в файловой системе (хотя некоторые оболочки допускают псевдонимы или функции с / в своем имени, которые затем принимают precendence).
Стефан Шазелас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.