Estou definindo um script de shell que um usuário deve source
executar em vez de.
Existe uma maneira convencional ou inteligente de sugerir ao usuário que esse é o caso, por exemplo, por meio de uma extensão de arquivo?
Existe um código shell que eu possa escrever no próprio arquivo, o que fará com que ele ecoe uma mensagem e saia se for executado em vez de originado, para que eu possa ajudar o usuário a evitar esse erro óbvio?
Supondo que você esteja executando o bash, coloque o seguinte código próximo ao início do script que deseja obter, mas não executado:
Em bash,
${BASH_SOURCE[0]}
conterá o nome do arquivo atual que o shell está lendo, independentemente de estar sendo originado ou executado.Por outro lado,
$0
é o nome do arquivo atual que está sendo executado.-ef
testa se esses dois arquivos são o mesmo arquivo. Se estiverem, alertamos o usuário e saímos.Nem são POSIX
-ef
.BASH_SOURCE
Embora-ef
seja suportado por ksh, yash, zsh e Dash,BASH_SOURCE
requer bash. Emzsh
, no entanto,${BASH_SOURCE[0]}
poderia ser substituído por${(%):-%N}
.Um arquivo não executável pode ser originado, mas não executado, portanto, como primeira linha de defesa, não definir o sinalizador executável deve ser uma boa dica ...
Editar: truque que acabei de descobrir: fazer o shebang ser qualquer executável que não seja um interpretador de shell,
/bin/false
faz com que o script retorne um erro (rc!=0)Existem vários métodos sugeridos nesta postagem do Stack Overflow , dos quais gostei mais do método baseado em função sugerido por Wirawan Purwanto e mr.spuratic :
Então você pode adicionar ao início do script:
Quando você origina um script de shell, a linha shebang é ignorada. Ao inserir um shebang inválido, você pode alertar o usuário de que o script foi executado erroneamente:
A mensagem de erro será esta:
O nome do argumento (arbitrário) já fornece uma dica forte, mas a mensagem de erro ainda não é 100% clara. Podemos corrigir isso com um script de utilitário
source-this-script
que é colocado em algum lugar no seuPATH
:Agora, a mensagem de erro será esta:
Comparação com outras abordagens
Em comparação com as outras respostas, essa abordagem requer apenas alterações mínimas em cada script (e ter uma linha shebang ajuda na detecção do tipo de arquivo nos editores e especifica o dialeto do script de shell, portanto, há até benefícios). A desvantagem é uma mensagem de erro pouco clara ou a adição (única) de outro script de shell.
Porém, não impede a invocação explícita via
bash path/to/script.sh
, (obrigado @muru!).Supondo que seja apenas inútil, em vez de prejudicial, executar o script, você pode adicionar
ao final do roteiro.
return
fora de uma função tem um código de saída diferente de zero, a menos que o arquivo esteja sendo originado.Aqui estão 4 técnicas que eu compilei. Você pode decidir programaticamente o que fazer se o script estiver sendo executado versus originado .
De check_if_sourced_or_executed.sh no meu repositório eRCaGuy_hello_world :
Comandos de execução de teste:
Veja também onde descrevi as 4 técnicas no Stack Overflow aqui: https://stackoverflow.com/questions/2683279/how-to-detect-if-a-script-is-being-sourced/70662049#70662049