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

У меня есть сценарий msource.sh который будет использоваться:

 $ 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" 

У меня есть сценарий, который будет источником 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 ${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 $! 

У меня есть другой скрипт mscript2.sh который будет вызываться mscript.sh , как показано выше:

 $ 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" 

Я запускаю все:

 $ 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 не экспортировать переменные. Если я вызываю функцию в subshell , поиск источника msource.sh или экспортирующих переменных по-прежнему не требуется.

Однако вызов другого скрипта в subshell теряет все переменные, и их нужно экспортировать, даже файл журнала, который будет переопределен в противном случае.

Может кто-нибудь уточнить, что происходит? В чем разница между выполнением функции в subshell и выполнением другого скрипта, который также будет запущен в другой subshell ? Почему не нужно экспортировать переменные родительского процесса для передачи в функцию subshell ?

Это по дизайну. Этот ответ на Unix & Linux SE объясняет эту проблему. Главное:

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

  • Сделать pendrive загрузочным через командную строку Ubuntu
  • Ssh и shell через ssh: как выйти?
  • Зацикливание результатов `ls` в скрипте оболочки bash
  • Передача двух аргументов команде с использованием труб
  • Как заменить команду результатом другого в Linux?
  • Написание сценариев оболочки, которые будут выполняться на любой оболочке (используя несколько строк shebang?)
  • Сценарий оболочки для исправления неправильных имен файлов?
  • Как вы избегаете апострофа в одиночной кавычки в bash?
  • Сценарий Bash & 'su', дающий ошибку «стандарт должен быть tty»,
  • Экран Gnu: выполнить команду при подключении
  • Как найти все ссылки (символические ссылки) в текущем каталоге?
  • Давайте будем гением компьютера.