Respostas:
Se você usar
sh ./<script>.run
/bin/sh
(geralmente um shell Bourne) será usado para executar o script. Claro que isso só funciona se o script for escrito para o shell Bourne. Às vezes, os scripts de shell para Linux exigem Bash em vez de Bourne, portanto, isso pode não funcionar, mesmo que seja um script de shell.
Se você usar
./<script>.run
o kernel examina a linha shebang para descobrir qual programa usar para executar o programa. Portanto, isso funciona mesmo que seja um Bash, Perl, Python ou algum outro script.
Portanto, essa é geralmente a maneira preferida de executar um script.
Contanto que seja um sh
script de shell (Dash ou equivalente), não, não há diferença externa.
O problema é .run
que não garante que é o caso. Pode ser binário. Pode ser Bash ou Python ou PHP ou o que for; todos eles têm um script de shell hash-bang. Se você forçar cegamente sh
, quem sabe o que poderia acontecer. Provavelmente haverá erros, mas poderia acidentalmente executar códigos nocivos antes de chegar tão longe.
Ao chmod
executá-lo (para ativar o bit de permissão de execução) e, em seguida, executá-lo ./script.run
, você oferece a melhor possibilidade possível de execução. Se for um script de shell, seu hash-bang será analisado corretamente e se for um executável binário, será executado nativamente.
Os dois métodos costumam agir da mesma forma, mas são muito diferentes.
sh ./script
executa o sh
comando com um argumento ./script
, que executa o script fornecido .. mesmo se o script não for realmente umsh
script (incorreto)
./script
executa o arquivo fornecido. Faz isso procurando o "shebang" linha para determinar qual comando executar. Se não especificado, ele usa sh
(isso os dois métodos agem da mesma maneira às vezes), mas geralmente um intérprete diferente é especificado.
Por exemplo, se filename
contém o seguinte:
#!/usr/bin/python
print "This is a Python script!"
.. então os dois comandos são muito diferentes:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Se não houver linha shebang, os dois serão os mesmos:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Uma diferença importante é se a sua linha hashbang possui parâmetros. Por exemplo, se o script começar com
#!/bin/bash -e
... e você o executa externamente usando sh
or bash
, essa linha será interpretada como um comentário e ignorada, para que o -e
parâmetro (saída em falha) não seja processado. Portanto, considerando o seguinte script:
#!/bin/bash -e
echo Hello
false
echo goodbye
A saída para ./script
será apenas "Olá", mas a saída para sh script
será Hello
seguida porgoodbye
, o que provavelmente não foi planejado.
A propósito, é por isso que você sempre deve usar uma set -e
declaração separada (é uma boa ideia - de qualquer maneira, se houver um problema no meio do script, você não quer que ela seja ignorada).