Это по замыслу. Этот ответ на Unix & Linux SE объясняет проблему. Основным моментом является:
Подоболочка […] отличается от выполнения скрипта.
У меня есть msource.sh
сценарий, который будет получен:
$ cat msource.sh #!/usr/bin/env sh echo "($BASHPID) - sourced $" &>> "$logfile" # logfile is defined by the sourcing script sourced_var="init sourced var with $BASHPID"
У меня есть скрипт, который будет исходить msource.sh
и вызывать function
как есть и в subshell
. Затем он вызовет другой скрипт mscript2.sh
:
$ cat mscript.sh #!/usr/bin/env sh logfile=mout.out rm -f $logfile source msource.sh mfun() { echo "($BASHPID) in $" &>> "$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 $!
У меня есть другой скрипт, mscript2.sh
который будет вызываться mscript.sh
, как показано выше:
$ cat mscript2.sh #!/usr/bin/env sh [ -z "$" ] && logfile=mout2.out || true echo "($BASHPID) - executing $" &>> "$logfile" echo " avar: '$avar'" &>> "$logfile" echo " sourced_var: '$sourced_var'" &>> "$logfile"
Я запускаю все:
$ bash script.sh
Я получаю следующие выводы:
$ 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'
а также
$ cat mout2.out (13179) - executing mscript2.sh avar: '' sourced_var: ''
Так что если я вызываю функцию как есть, то pid
это то же самое, и мне не нужно msource.sh
ни исходить, ни экспортировать переменные. Если я вызываю функцию в a subshell
, поиск msource.sh
или экспорт переменных по-прежнему не требуется.
Однако при вызове другого скрипта в a subshell
теряются все переменные, и их необходимо экспортировать, даже файл журнала, который в противном случае будет переопределен.
Может кто-нибудь уточнить, что происходит? В чем разница между выполнением функции в a subshell
и выполнением другого скрипта, который также будет запущен в другом subshell
? Почему не нужно экспортировать переменные родительского процесса для передачи в функцию subshell
ed?
Это по замыслу. Этот ответ на Unix & Linux SE объясняет проблему. Основным моментом является:
Подоболочка […] отличается от выполнения скрипта.