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 comando 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

Agora, quando executo o jdev , ele executa uma versão diferente do Oracle JDveloper do que quando eu corro como ./jdev .. Por que é assim?

    
por Geek 22.01.2013 / 10:04

4 respostas

21

Quando você executa um arquivo executável (ou melhor, no mundo unix / linux - um arquivo com direitos / sinalizações executáveis), assim:

$ ./jdev

você, em seguida, marca com . que deseja executar um arquivo dentro de seu diretório de trabalho (diretório em que você está atualmente) que é denominado jdev e possui direitos executáveis para o usuário que o está iniciando (você precisa note que ainda pode ser um link para outro arquivo, você pode verificar isso digitando ls -l jdev no terminal)

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

Quando você o executa como

$ jdev

então, é provável que haja jdev instalado em algum lugar do sistema e você o tenha em $PATH (por exemplo, /usr/bin/ ou /bin/ ou /usr/local/bin/ )

Como peterph afirmou: você pode usar which para apontar o executável que está sendo lançado com comando, por exemplo:

$ which find
/usr/bin/find
    
por 22.01.2013 / 10:10
8

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

Se houver uma barra no nome, então isso não acontece, o nome é tomado como um caminho para executar o comando (embora alguns shells como zsh permitam que aliases ou funções tenham barras em seu nome, o que então tenha precedência).

Portanto, se você quiser executar um comando chamado foo que 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 deve executar, use o comando type . Não use o comando which , que geralmente não faz o que você pensa e é uma herança de csh , o que é melhor deixar em paz.

    
por 22.01.2013 / 11:37
2

Eu recomendo usar o 'where' interno do Zsh (melhor que 'which') para ver como e em qual ordem aliases, shell embutidos 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:~ %
    
por 23.01.2013 / 00:12
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 . representa o diretório atual (na verdade, ls -all . forneceria o mesmo que ls -all ). Se você fizer /usr/bin/tool/ , você está usando um caminho absoluto. Nestes casos, o arquivo apontado é executado.

  • Se você não fornecer um caminho, mas apenas um nome, os diretórios em $PATH serão procurados pela 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 em $PATH e executá-lo com a inclusão de ./ em seu nome, você executará efetivamente um arquivo diferente.

Talvez outro problema seja o fato de você estar realmente esperando que jdev execute o executável no diretório atual. A menos que você tenha alterado $PATH para incluir . , isso não é algo que você deve esperar ...

... e ainda não é uma boa idéia incluir . , se você o fizer, por favor, pelo menos, coloque-o no final, para que o resto de $PATH seja sempre pesquisado primeiro - apenas imagine que você está em um diretório de rede compartilhado e alguém decide colocar um binário maligno lá como ls , se $PATH começar com . , um simples ls -lah será suficiente para atacar seu sistema.

    
por 22.01.2013 / 10:34