Qual é a diferença entre executar um executável apenas pelo nome e anexar um ponto / barra antes dele?

13

Esta é a saída do ls -allcomando:

-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

Agora, quando apenas executo, jdevele executa uma versão diferente do Oracle JDveloper do que quando executo como ./jdev.. Por que é isso?

Nerd
fonte

Respostas:

20

Quando você executa um arquivo executável (ou melhor, no mundo unix / linux - um arquivo com direitos executáveis ​​/ sinalizador ativado) da seguinte forma:

$ ./jdev

você marca com o .que deseja executar um arquivo dentro do diretório de trabalho (diretório em que está atualmente) nomeado jdeve com direitos executáveis ​​para o usuário que o está iniciando (é necessário observar que ele ainda pode ser um link para outro arquivo, você pode verificar isso digitando ls -l jdevno terminal)

(veja permissões de arquivo no linux / unix )

Quando você o executa como

$ jdev

então provavelmente há jdevalgum lugar instalado no sistema e você o possui $PATH(por exemplo, /usr/bin/ou /bin/ou /usr/local/bin/)

Como peterph afirmou: você pode usar whichpara apontar o executável que está sendo iniciado com um comando específico, por exemplo:

$ which find
/usr/bin/find
Patryk
fonte
1
Também não é que o whichutilitário possa dizer qual executável será usado se nenhum caminho for fornecido.
Peterph
@peterph Editou minha resposta.
quer
7
É muito melhor usar typepara verificar o que é iniciado por um comando específico. A causa whichmostrará apenas um binário em algum lugar do $ PATH, no entanto, pode estar alias a absolutamente outro binário.
apressar
@rush I tem apenas tentei isso e não trabalho será como você diz: [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Enquantozsoelim -> soelim
Patryk
2
@ Patryk Eu acho que rush significava os apelidos / funções do shell, que whichnão têm chance de encontrar, uma vez que é um binário independente que não tem acesso ao ambiente shell em execução (com o que quero dizer apelidos e funções, não apenas as variáveis ​​de ambiente , alguns dos quais são herdados).
Peterph
8

Se você chamar um comando sem barra em seu nome em um shell, ele será procurado nos aliases, funções e na lista de caminhos fornecidos na $PATHvariável de ambiente. (observe que você pode ter o diretório de trabalho atual (especificado como .ou a cadeia vazia) ou qualquer diretório relativo $PATH, mas isso não é recomendado por razões de segurança).

Se houver uma barra no nome, isso não acontecerá, o nome será usado como um caminho para executar o comando (embora alguns shells, como por exemplo, zshpermitam que aliases ou funções tenham barras no nome, os quais teriam precedência).

Portanto, se você deseja executar um comando chamado fooque está no diretório de trabalho atual, é necessário criar um nome que contenha uma barra. ./fooé o mais óbvio. Você também pode usar o caminho completo ou ../dir/foo...

Para saber o que o shell executaria, use o typecomando Não use o whichcomando que geralmente não faz o que você pensa que faz e é uma herança da cshqual é melhor ficar sozinho.

Stéphane Chazelas
fonte
Por que não "qual", mas "tipo"?
22413 Geek
@ Geek, essa é uma FAQ aqui, consulte unix.stackexchange.com/search?q=[qualquer+++ tipo #
Stéphane Chazelas
você forneceu o link correto?
22413 Geek
Esse é um resultado de pesquisa neste site para provar que é uma pergunta freqüente. Muitas respostas para essas perguntas lhe dirão por que não usar which. Veja, por exemplo, unix.stackexchange.com/questions/16693/…
Stéphane Chazelas
2

Eu recomendo usar o 'where' interno do Zsh (melhor que 'what') para ver como e em qual ordem os aliases, os shell shell ou qualquer outra coisa será encontrada para $ PATH ;-)

Aqui está um exemplo para entender melhor as coisas, como é escolhido:

[ 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:~ %
Afsin Toparlak
fonte
1

Embora isso provavelmente dependa do seu shell, a regra geralmente é:

  • Se você fornecer um caminho, relativo ou absoluto, esse caminho será usado. ./jdevé um caminho relativo, porque .significa o diretório atual (na verdade, ls -all .daria o mesmo que ls -all). Se fizer isso /usr/bin/tool/, você está usando um caminho absoluto. Nesses casos, o arquivo apontado é executado.

  • Se você não fornecer um caminho, mas apenas um nome, os diretórios $PATHserão pesquisados ​​em busca da ferramenta que você está tentando executar.

Se você tiver um arquivo no diretório atual com o mesmo nome de um arquivo em alguns dos diretórios do diretório $PATHe o executar acrescentando ./o nome dele, efetivamente executará um arquivo diferente.

Talvez outro problema seja que você esperava jdevexecutar o executável no diretório atual. A menos que você tenha alterado $PATHpara incluir ., isso não é algo que você deve esperar ...

... e ainda não é uma boa ideia incluí .-la, se você o fizer, pelo menos coloque-o no final, para que o resto $PATHseja sempre pesquisado primeiro - imagine que você esteja em um diretório de rede compartilhado e alguém decide colocar um binário maligno lá ls, pois , se $PATHcomeçar ., um simples ls -lahserá suficiente para atacar seu sistema.

njsg
fonte
Sua terminologia é confusa. jdevsozinho também é um caminho relativo. A regra é: se não contém uma barra, é pesquisada em aliases, funções e $PATH, caso contrário, é pesquisada diretamente no sistema de arquivos (embora alguns shells permitam aliases ou funções com / em seu nome, o que seria necessário precedência).
Stéphane Chazelas