./ vs. para executar programas no terminal

13

Eu precisaria de alguns esclarecimentos sobre a maneira como executamos os executáveis ​​no terminal. Essa pode ser uma pergunta esfarrapada, mas qual é a diferença entre executar um executável com ./an_executablee . an_executable(vamos supor que estamos no diretório em que um an_executable está localizado)

Eu já sei que o primeiro faz com que o shell procure por um_executável no diretório atual ( .), mas por que não é /necessário depois de .usar a última versão?

Desde já, obrigado.

zipzap
fonte
Veja também askubuntu.com/q/182012/26972
ysap 13/02/2015

Respostas:

22

A . executablesintaxe não funciona com nenhum executável (ou funciona?). Em vez disso, é um alias para o bash sourceembutido. Portanto, a diferença é principalmente relevante para os scripts do bash, e a verdade é que são coisas completamente diferentes :)

./executablepede para executar o executável "normalmente". ./é uma referência relativa ao caminho atual. Isso evita que o shell (bash) tente localizar o executável em um diretório $PATH(o que faria se você não especificasse um caminho com o comando). A razão pela qual você não pode simplesmente fazer isso executableé de segurança; imagine que você descompacta um arquivo baixado e ele contém uma versão maliciosa ls. Se ele fosse executado diretamente do seu diretório atual, você executaria essa versão sem perceber.

Por outro lado, . executableestá dizendo "origine um arquivo chamado executable". Como você está nomeando o arquivo diretamente e ele realmente não precisa ser um executável, a restrição de segurança do $ PATH não se aplica. O fornecimento apenas "executará" (ou parecerá executar) scripts de shell. O que ele faz é:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Então ... Qual é realmente a diferença entre executar e terceirizar? Supondo que o mesmo script de shell, executá-lo ( ./script) gerará um novo shell, execute o script dentro desse shell e, quando o script sair, feche esse shell e retorne ao shell pai. Com efeito, ele iniciará um novo bashprocesso para executar o script).

( . script) fará com que o shell atual leia os comandos do arquivo como se estivessem sendo digitados na linha de comando. Não há nova concha gerada.

Uma maneira muito fácil de ver como isso se comporta é escrever um script que contenha apenas exit. Se você ./script, nada parece acontecer, isso ocorre porque um novo processo de shell é iniciado, o exitcomando sai desse novo shell e seu shell atual não é afetado.

Se você . script, seu terminal atual será fechado, porque o exitcomando é executado no shell atual. Portanto, é equivalente a digitar exitno prompt de comando.

roadmr
fonte
Na verdade, eu estava lidando com shell script quando percebi esse comportamento. Muito obrigado, essa é a resposta que eu precisava. :)
zipzap 12/02
outra questão levantada (se você não se importa): se meu script contém apenas algumas mensagens simples com eco, e eu o estou executando com ./script, então por que eu consigo ver as mensagens no shell pai se o subshell fecha assim que a execução terminar?
ZipZap
2
Como o subshell é um processo separado , ele usa o mesmo terminal que o shell de chamada. É semelhante a como você ainda pode ver a lssaída: você digita o comando, ele executa, mostra a saída e depois termina, mas a saída permanece no terminal.
roadmr
2
Não confunda shell com terminal; são coisas diferentes. Abra um terminal e o prompt de comando é fornecido por um bashshell executando dentro dele. Se você digitar bash, estará executando outro shell; para o primeiro shell, é apenas um programa a ser executado. Se você digitar exit, fechará o último shell iniciado, mas ainda estará no primeiro (o de quando você iniciou o terminal). Novamente, tudo isso acontece dentro do mesmo terminal.
roadmr
1
@ DavidZ Eu mencionei isso :) "O Sourcing apenas" executa "(ou parece executar) scripts de shell".
roadmr 12/02/2015