Bash: detectar executar vs fonte em um script?

19

Eu tenho um script que está espalhado pelo meu sistema de arquivos (efeito colateral de um processo de compilação) que define algumas variáveis ​​de ambiente global (LD_LIBRARY_PATH, PATH, ROOTDIR etc.) que precisam estar no meu shell para uma operação adequada. Obviamente, isso significa que eu preciso source script.shou . script.shfazê-lo funcionar, e não ./script.sh(o que geraria um novo shell e não definiria as variáveis ​​no meu shell atual).

Existe algo que eu possa adicionar ao script para impedir (ou avisar) alguém em execução ./script.sh?

Yeraze
fonte

Respostas:

15

Em um script de shell, $0é o nome do script em execução no momento. Você pode usar isso para saber se está sendo originado ou executado da seguinte maneira:

if [[ "$(basename -- "$0")" == "script.sh" ]]; then
    echo "Don't run $0, source it" >&2
    exit 1
fi
Mikel
fonte
5

A maneira mais simples de entrar bashé:

if [ "$0" = "$BASH_SOURCE" ]; then
    echo "Error: Script must be sourced"
    exit 1
fi

$BASH_SOURCE sempre contém o nome / caminho do script.

$0 contém apenas o nome / caminho do script quando NÃO é originado.

Portanto, quando eles correspondem, isso significa que o script NÃO foi originado.

wisbucky
fonte
1

Isso foi discutido no SO . A resposta mais votada por @barroyo diz para usar

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."
serv-inc
fonte
@ will: O manual diz: Uma variável de matriz cujos membros são os nomes de arquivos de origem onde são definidos os nomes das funções de shell correspondentes na variável de matriz FUNCNAME. Como uma função?
serv-inc
1

Outra opção pode ser remover permissões de execução. Nesse caso, não pode ser executado, mas ainda pode ser originado.

Jelmer
fonte
1
Isso está incompleto. Você ainda pode executar scripts bash scriptindependentemente do sinalizador de execução em um script. Também em Cygwin (isso conta?), Você não pode remover as bandeiras de execução.
Tino
0

Além de marcar $ 0 ( resposta Mikel ), pode ser útil alterar a extensão de .sh para .src, por exemplo. Isso ajudará a entender quem não deve executar esse script.

Victor Sizov
fonte
0

Crie um intérprete personalizado source_reminder:

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

Não se esqueça de torná-lo executável. Em seguida, basta usá-lo em seu script:

#!/path/to/your/source_reminder
foo
bar
whatever

Agora, se você executar o script sem fonte, o lembrete fará seu trabalho.

Kamil Maciorowski
fonte
Boa pegada. #!/bin/echo do not executeou #!/bin/falseou #!/usr/bin/awk BEGIN { print "you must source " ARGV[1]; exit(1) }. No entanto, isso não ocorre no caso em que o script é executado com algo parecido sh script(pois isso ignora o Shebang).
Tino