Нет необходимости в экспорте при запуске функций в подоболочке

654
kaligne

У меня есть 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? Почему не нужно экспортировать переменные родительского процесса для передачи в функцию subshelled?

0

1 ответ на вопрос

1
Kamil Maciorowski

Это по замыслу. Этот ответ на Unix & Linux SE объясняет проблему. Основным моментом является:

Подоболочка […] отличается от выполнения скрипта.