Isso é por design. Esta resposta no Unix & O Linux SE explica o problema. O ponto principal é:
A subshell is […] different from executing a script.
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?
Isso é por design. Esta resposta no Unix & O Linux SE explica o problema. O ponto principal é:
A subshell is […] different from executing a script.
Tags bash daemon export pid shell-script