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.