Chamar as funções do arquivo de origem no script bash

2

Eu tenho um arquivo bash src-useful.bash, contendo funções úteis como say_hello(), localizadas em / path / to / useful.

No meu ~/.bash_profileeu adicionei as seguintes linhas:

export BASH_USEFUL=/path/to/useful
source $BASH_USEFUL/src-useful.bash

Abrindo um novo terminal, posso verificar o seguinte:

$ echo $BASH_USEFUL
/path/to/useful

$ cat $BASH_USEFUL/src-useful.bash
function hello() {
    echo "hello!"
}

$ hello
hello!

Eu criei um script say_hello.sh:

$ cat say_hello.sh
echo "BASH_USEFUL: $BASH_USEFUL"
hello

$ ./say_hello.sh
BASH_USEFUL: /path/to/useful  # Recognizsed
say_hello.sh: line 2: say_hello: command not found  # Not recognized?

Se eu source $BASH_USEFUL/src-useful.bashem say_hello.shque vai funcionar no entanto:

$ cat say_hello.sh
echo "BASH_USEFUL: $BASH_USEFUL"
source $BASH_USEFUL/src-useful
say_hello

$ ./say_hello.sh
BASH_USEFUL: /path/to/useful  # Recognized
hello!  # Function say_hello is now recognized

Gostaria de saber por que a variável BASH_USEFULainda é reconhecida pelo meu script, enquanto as funções do meu arquivo de origem não podem ser vistas no ambiente pelo meu script em execução. Existe uma solução alternativa, além de fornecer meus src-useful.bashem meus scripts? Gostaria que src-useful.bashas funções fossem carregadas no ambiente de qualquer script iniciado.

Kaligne
fonte
Parece que você alterou a chamada para a função originada hello()para say_hello()nas etapas acima ...
venzen
Ah sim obrigado, eu corrigi. O problema ainda está aqui, porém
kaligne
Essa é ... uma maneira horrível de escrever programas. Vai morder você mais cedo ou mais tarde.
grawity
Graças grawity, como devo fonte minhas funções genéricas então?
kaligne

Respostas:

3

Somente itens de ambiente exportados são copiados para novos ambientes filho. Você exportou BASH_USEFULpara que este env-var seja copiado para o seu ./say_hello.shsubprocesso conforme o esperado. Mas você não fez o mesmo com sua função, hello()que é um símbolo local simples que não deve ser copiado em novos ambientes filho.

A sintaxe para exportar funções usando o bash usa o -fargumento de export:

export -f hello
A. Loiseau
fonte
Isso significa que eu poderia exportar manualmente todas as funções (yuk) ou originar o arquivo em todos os meus scripts?
kaligne
Sim. Mas exportar todas as funções pode ser bastante fácil se você pensar sobre isso ao escrever seus scripts. Você pode: 1) adicionar um export -fcorpo após cada função, ou 2) adicionar um MYSCRIPT_FUNCS="${MYSCRIPT_FUNCS} foo"corpo após cada função com uma função auxiliar extra myscript_export_all()que chama export -ftodos os tokens dessa variável, por exemplo. E importe esse script usando uma sintaxe como source myscript.sh && myscript_export_all.
A. Loiseau