Existem três opções que uso quando tenho um script bash que quero comportar de maneira diferente quando é originado vs. quando é executado (ou em outras palavras, tenho itens de dados em um script que eu quero acessar sem executar nenhum código nesse momento). Os comentários tocaram neles até certo ponto.
Opção 1
Determine quando é originado e termine 'sourcing' no momento adequado
Separe o script em duas seções, saia do script quando for originado antes de chegar ao segundo inferior
Crie uma seção superior do script com definições (funções / atribuições de variáveis / etc), mas sem execução direta de código.
Pouco antes do início da seção do código executável, coloque a lógica que sairá do script se detectar que está sendo originada. O segmento de código a seguir fará isso:
file1.sh
#!/usr/bin/env bash
export var1="/data/share"
export var2='password'
# --- End Definitions Section ---
# check if we are being sourced by another script or shell
[[ "${#BASH_SOURCE[@]}" -gt "1" ]] && { return 0; }
# --- Begin Code Execution Section ---
echo "Hello"
echo $var1
echo $var2
file2.sh
#!/usr/bin/env bash
source file1.sh
echo "$var1"
echo "$var2"
Saída da execução de ./file2.sh
$ ./file2.sh
/data/share
password
Opção Dois
Este normalmente só é usado em situações complexas e, para esse exemplo específico, é um exagero. Crio uma função no arquivo que desejo originar e, nessa função, determino o que deve estar disponível para o chamador. Neste caso, são as duas variáveis exportadas. Normalmente eu uso este modo quando tenho matrizes associativas, que são quase impossíveis de serem distribuídas. Além disso, o arquivo tmp deve ser excluído pelo chamador; mas eu não fiz neste caso:
file1.sh
#!/usr/bin/env bash
export var1="/data/share"
export var2='password'
exportCfg() {
tmpF=$(mktemp)
declare -p var1 var2 > "$tmpF"
echo "$tmpF"
}
if [ "$1" == "export" ]; then
exportCfg;
exit 0;
fi
echo "Hello"
echo $var1
echo $var2
file2.sh
#!/usr/bin/env bash
source $(./file1.sh export)
echo "$var1"
echo "$var2"
A saída da execução de file2.sh é a mesma que acima
Opção 3
A forma comum final com que lidei com isso é simplesmente com um arquivo de biblioteca que apenas contém definições e não possui código que será executado quando originado ou executado diretamente. Isso é simplesmente uma questão de dividir seu código. Eu tenho um grupo de bash 'libs' que contêm funções usadas com freqüência, e em uma base por projeto geralmente configuram uma pequena biblioteca de origem para armazenar dados de configuração (constantes). Se esses dados incluírem matrizes preenchidas, também usarei uma versão da Opção 2.