Qual é a diferença entre executar “ bash script.sh ” e “ ./script .sh ”?

Se script.sh for apenas algo típico como

#!/bin/bash echo "Hello World!" 

Existe um preferido maneira de executar o script? Acho que você deve primeiro fazer o chmod para que se torne executável?

Resposta

Para o seu script específico, qualquer uma das formas funcionará, exceto que ./script.sh requer execução e bits legíveis, enquanto bash script.sh requer apenas bits legíveis.


O motivo de a diferença de requisitos de permissões está em como o programa que interpreta seu script é carregado:

  • ./script.sh faz seu shell executar o arquivo como se fosse um arquivo normal executável.

O shell se bifurca e usa uma chamada de sistema (por exemplo, execve) para fazer o sistema operacional executar o arquivo no processo bifurcado. O sistema operacional verificará as permissões do arquivo (portanto, o bit de execução precisa ser definido) e encaminhará a solicitação para o carregador de programa , que examina o arquivo e determina como executá-lo. No Linux, os executáveis compilados começam com um número mágico ELF , enquanto os scripts começam com um #! ( hashbang ). Um cabeçalho hashbang significa que o arquivo é um script e precisa ser interpretado pelo programa especificado após o hashbang. Isso permite um script para dizer ao sistema como interpretar o script.

Com o seu script, o carregador do programa executará /bin/bash e passará ./script.sh como o argumento da linha de comando.

  • bash script.sh faz seu shell executar bash e passar script.sh como o argumento da linha de comando

Portanto, o sistema operacional carregará (nem mesmo olhando para script.sh, porque é apenas um argumento de linha de comando). O processo bash criado interpretará o script.sh porque foi passado como o argumento da linha de comando. Porque script.sh só é lido por bash como um arquivo normal, o bit de execução não é necessário.


Eu recomendo usar ./script.sh entretanto, porque você pode não saber qual interpretador o script está exigindo. Portanto, deixe o carregador do programa determinar isso para você.

Comentários

  • Se o bit executável não estiver definido, você também pode executar o script fazendo ". ./script.sh"
  • @Dog Você está correto. O ponto é um atalho para o comando embutido ' source ' , que executa o script no processo bash atual. Portanto, apenas o bit legível é necessário.
  • @Dogeatcatworld embora seja verdade, executar . ./script.sh não é o mesmo algo como (ou ./script.sh. Considere o script #!/usr/bin/python -V < newline > print test.
  • Esteja ciente de que a origem de um script pode resultar na contaminação da sessão interativa. Por exemplo, se um script alterar a variável de ambiente PATH, essa alteração afetará os comandos executados após a origem. Essa abordagem deve ser reservada para situações em que você depende dos efeitos colaterais (scripts de configuração de ambiente e similares). Para outras situações em que você pode ' t alterar as permissões, executar o comando na linha shebang, seguido pelo nome do script, é a abordagem mais segura.
  • Observe que , se você criar um script no diretório atual, não precisará usar ./ ; basta dizer . script.sh. Mas concordo com as pessoas que desencorajam o uso do comando . em scripts que não deveriam ser invocados dessa forma. Estou surpreso que ninguém mencionou que, se o script contiver exit comandos e você o fornecer, ele poderá desconectá-lo. Um problema menos terrível seria se o script fizesse um cd, pois isso também afetaria o shell pai (interativo).

Resposta

bash script.sh invoca o script diretamente usando o bash.
./script.sh está usando o shebang #!/bin/bash para determinar como executar.

Se você realmente deseja saber, qual binário é executado se você fizer um bash script.sh você pode descobrir com which bash.

Portanto, em seu exemplo, isso não faz diferença. Sim, você deve chmod +x script.sh para poder executá-lo diretamente por meio de ./script.sh.

Comentários

  • Bem, não faz diferença supor que /bin/bash seja o primeiro bash em seu $PATH.
  • Você ' está certo. E o shebang #!/bin/bash só funciona se houver um /bin/bash
  • Bash (versão 4.2.37) no meu sistema executa scripts mesmo sem o conjunto de bits de execução. Por que você diz que o bit de execução é necessário?
  • Sim, o bit de execução só é necessário invocando via ./script.sh.

Resposta

Crie um arquivo Delete_Self.sh como este:

 #!/bin/rm echo I am still here! 

Execute isto script como sh Delete_Self.sh você verá “Ainda estou aqui!” ecoado de volta.

Torne-o executável e execute-o como ./Delete_Self.sh você verá que nada é ecoado de volta, enquanto o arquivo Delete_Self.sh se foi.

Portanto, a diferença é que:

  • bash script.sh irá ignorar o #! linha, porque bash é especificado como o programa para executar script.sh.
  • ./script.sh lerá o #! linha para determinar o programa a ser executado script.sh.

Comentários

  • +1 para o bom exemplo

Resposta

Além das outras respostas, sabendo a diferença entre executar um script por meio de ./script.sh (i) e fonte ./script.sh (ii) é útil – A versão (i) cria um novo shell no qual executar o comando, enquanto (ii) o executa no shell atual – o que pode ser obrigatório se o executável alterar as variáveis de ambiente que precisam ser preservadas após a saída do executável. Por exemplo, para ativar um ambiente python conda, deve-se usar o seguinte:

source activate my_env 

N.B. Outra alternativa para source que você pode encontrar é o . integrado, ou seja,

. activate my_env 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *