Não há necessidade de exportar ao executar funções em subshell

0

Eu tenho um script msource.sh que será originado:

$ cat msource.sh 
#!/usr/bin/env sh
echo "($BASHPID) - sourced ${BASH_SOURCE[0]}" &>> "$logfile"
  # logfile is defined by the sourcing script
sourced_var="init sourced var with $BASHPID"

Eu tenho um script que vai fonte msource.sh e chamar um function como está e em um subshell . Em seguida, ele chamará outro script mscript2.sh :

$ cat mscript.sh 
#!/usr/bin/env sh

logfile=mout.out
rm -f $logfile
source msource.sh

mfun() {
  echo "($BASHPID) in ${FUNCNAME}"  &>> "$logfile"
  echo "  avar: '$avar'" &>> "$logfile"
  echo "  sourced_var: '$sourced_var'" &>> "$logfile"
}

avar="$BASHPID - init"

echo "[mfun] basic call" &>> "$logfile"
mfun

echo -e "\n[mfun &] subshell call" &>> "$logfile"
mfun &
wait $!

## call mscript2.sh
echo -e "\n[mscript2] background call" &>> "$logfile"
bash mscript2.sh &
wait $!

# call mscript2.sh after exporting variables
echo -e "\n[mscript2 &] export and background call" &>> "$logfile"
export logfile
export avar
export sourced_var
bash mscript2.sh &
wait $!

Eu tenho outro script, mscript2.sh , que será chamado por mscript.sh , como visto acima:

$ cat mscript2.sh
#!/usr/bin/env sh

[ -z "${logfile:+x}" ] && logfile=mout2.out || true

echo "($BASHPID) - executing ${BASH_SOURCE[0]}" &>> "$logfile"
echo "  avar: '$avar'" &>> "$logfile"
echo "  sourced_var: '$sourced_var'" &>> "$logfile"

Eu corro tudo:

$ bash script.sh

Eu recebo as seguintes saídas:

$ cat mout.out 
(13166) - sourced msource.sh
[mfun] basic call
(13166) in mfun
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

[mfun &] subshell call
(13174) in mfun
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

[mscript2 &] background call

[mscript2 &] export and background call
(13184) - executing mscript2.sh
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

e

$ cat mout2.out 
(13179) - executing mscript2.sh
  avar: ''
  sourced_var: ''

Portanto, se eu chamar a função como está, o pid é o mesmo e não preciso originar o msource.sh nem exportar as variáveis. Se eu chamar a função em subshell , o fornecimento de msource.sh ou as variáveis de exportação ainda não serão necessárias.

No entanto, chamar outro script em subshell perde todas as variáveis e elas precisam ser exportadas, até mesmo o arquivo de log que será redefinido de outra forma.

Alguém pode esclarecer o que está acontecendo? Qual é a diferença entre executar uma função em subshell e executar outro script, que também será lançado em outro subshell ? Por que as variáveis de um processo pai não precisam ser exportadas para serem passadas para uma função subshell ed?

    
por kaligne 05.07.2017 / 01:54

1 resposta

1

Isso é por design. Esta resposta no Unix & O Linux SE explica o problema. O ponto principal é:

A subshell is […] different from executing a script.

    
por 10.07.2017 / 10:54