Este é um extrato do manual ( man sh
): -
If command line arguments besides the options have been specified,
then the shell treats the first argument as the name of a file from
which to read commands (a shell script), and the remaining arguments
are set as the positional parameters of the shell ($1, $2, etc).
Otherwise, the shell reads commands from its standard input.
Assim, em sh file.sh
, o arquivo file.sh
especificado se torna uma fonte de entrada para o shell, portanto, precisa ser legível, mas não precisa ser executável. O mesmo vale para o comando source
ou .
, portanto, o seguinte executará um arquivo não executável: -
sh ./file.sh
sh<./file.sh
. ./file.sh
source ./file.sh
Os dois últimos serão executados no shell atual, os dois primeiros em um sub-shell. Observe que sh -c ./file.sh
exigirá file.sh
para executável, enquanto sh -c ". ./file.sh"
não precisa. Observe também que, se file.sh
for executável, sua localização precisará estar em $PATH
se for chamada diretamente, a menos que um caminho específico ( ./
no exemplo) seja incluído:
file.sh
No entanto, os quatro exemplos anteriores não precisam do prefixo ./
, pois o arquivo a ser lido sempre será procurado no diretório atual (embora os comandos .
e source
também pesquisem $PATH
).
Dois pontos finais: -
- Os quatro exemplos funcionam apenas para arquivos de script: todos eles falharão se
file.sh
for um executável binário.
- Nos quatro exemplos, o comentário
#!/bin/bash
é apenas um comentário: a execução sh
irá lê-lo como tal e não clonará bash
para executar o resto do arquivo, então, qualquer extensão bash
causará erros.