Importando variáveis em um script de shell de outro sem executar o script de shell referido

2

Eu tenho 2 scripts de shell, file1.sh e file2.sh

file1.sh

#!/usr/bin/env bash 
export var1="/data/share"
export var2='password'
echo "Hello"

file2.sh

#!/usr/bin/env bash 
source file1.sh
echo $var1
echo $var2

Quando executo file2.sh, recebo a seguinte saída

Hello
/data/share
password

Mas minha saída esperada é

/data/share
password

file1.sh está sendo executado quando referido em file2.sh. Como importo as variáveis sozinhas no arquivo2.sh sem executar o arquivo1.sh?

    
por Mathew 17.06.2016 / 12:12

2 respostas

2

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.

    
por 19.06.2016 / 10:56
2

Se todas as suas variáveis forem exportadas da mesma forma ( export foo = bar ), você poderá obter todas elas facilmente usando o bash recurso de substituição de processos:

source <(grep '^export .*=' file1.sh)

Extrato da página do manual:

Process Substitution Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of <(list) or >(list). The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list.

    
por 19.06.2016 / 14:32