Eu tenho o seguinte script chamado .bash_functions.test
que já é originado pelo meu .bash_functions
script:
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
E quando executo a test1
função, vejo isso:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
Finalmente, quando eu origino o script mais uma vez e executo novamente a test1
função, vejo isso:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Na verdade, eu uso minha Source
função na primeira chamada de origem e na chamada source
interna e na segunda de origem:
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
E aqui está o que acontece:
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Por que está funcionando assim?
declare
/typeset
sem-g
declara variáveis no escopo atual, além de definir o tipo.Aqui, porque
declare -A audioExtension=(...)
acaba sendo executado dentro daSource
função, isso faz com que aaudioExtension
variável seja declarada local para essa função e, como consequência, sua definição seja perdida quandoSource
retornar.Você pode alterá-lo para
typeset -Ag audioExtension=(...)
que sempre declara a variável no escopo global (é diferente de zsh/mksh/yash ondetypeset -g
apenas impede que a variável seja local (apenas atualiza o tipo/atributos e valor); faz diferença quando suaSource
função é chamado de outra função; veja bash vs zsh: scoping e `typeset -g` para detalhes).Se você usou
ksh93
em vez debash
(esse é o shellbash
emprestado dessa sintaxe de matriz associativa), você pode definir suaSource
função como:ao contrário de:
No ksh93, as funções definidas com a sintaxe no estilo Bourne
func() cmd
não têm escopo local, enquantofunction func {
as funções têm escopo local estático (há apenas um escopo global e um escopo local por função, não uma pilha de escopos locais).Em
bash
(e em outros shells com escopo local), não há maneira semelhante de ter uma função que não introduza um novo escopo. Você poderia usar umalias
em vez como:(observe que os aliases são expandidos no momento em que o código é lido , não no momento em que é executado ).
Isso faria uma diferença funcional em comparação com sua abordagem de função em:
Estaríamos cronometrando ambos
source myfile
eother-cmd
, como é expandido paratime source ./myfile | other-cmd
while na abordagem da função, faríamos apenas cronometrandosource ./myfile
.Usar
source=(time source); "${source[@]}" /some/file
não funcionaria (ele invocaria otime
utilitário autônomo em vez da palavra-bash
chave time).