Bash: detecta executar vs source em um script?

13

Eu tenho um script que está em volta do meu sistema de arquivos (efeito colateral de um processo de compilação) que define algumas variáveis de ambiente globais (LD_LIBRARY_PATH, PATH, ROOTDIR, etc) que precisam estar em meu shell para operação adequada. Obviamente, isso significa que eu preciso de source script.sh ou . script.sh para fazê-lo funcionar, e não de ./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 executando ./script.sh ?

    
por Yeraze 20.03.2014 / 15:50

6 respostas

11

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

if [[ "$(basename -- "$0")" == "script.sh" ]]; then
    echo "Don't run $0, source it" >&2
    exit 1
fi
    
por 20.03.2014 / 16:04
2

A maneira mais simples em 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.

Então, quando eles correspondem, significa que o script NÃO foi originado.

    
por 24.01.2018 / 20:40
1

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

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."
    
por 14.10.2015 / 09:30
1

Para detectar casos em que o script é chamado de outro diretório, você precisa usar basename nos dois, $0 e ${BASH_SOURCE[0]} . Claramente, isso é bashismo, portanto, outras camadas precisam alterar ${BASH_SOURCE[0]} para uma variável apropriada.

#!/bin/bash
if [[ $(basename -- "$0") == $(basename -- "${BASH_SOURCE[0]}") ]]; then
  echo "Sourcing the script (${BASH_SOURCE[0]})" >&2
  source "${BASH_SOURCE[0]}"
  exit 0;
fi
    
por 07.02.2017 / 22:50
1

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

    
por 20.06.2018 / 13:29
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. Então, basta usá-lo em seu script executável:

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

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

    
por 20.06.2018 / 13:49

Tags