简体   繁体   English

bash shell 脚本和脚本中函数的变量范围

[英]Variable scope for bash shell scripts and functions in the script

I'm a little confused with my script regarding functions, variable scope, and possibly subshells.我对我的脚本在函数、变量范围和可能的子shell 方面有点困惑。 I saw in another post that pipes spawn a subshell and the parent shell can't access variables from the subshell.我在另一篇文章中看到管道产生了一个子外壳,而父外壳无法从子外壳访问变量。 Is this the same case with cmds run in backticks too?这与 cmds 在反引号中运行的情况相同吗?

To not bore people, I've shortened my 100+ line script but I tried to remember to leave in the important elements (ie backticks, pipes etc).为了不让人厌烦,我缩短了 100 多行脚本,但我尽量记住保留重要元素(即反引号、竖线等)。 Hopefully I didn't leave anything out.希望我没有遗漏任何东西。

global1=0
global2=0
start_read=true

function testfunc {
   global1=9999
   global2=1111
   echo "in testfunc"
   echo $global1
   echo $global2
}

file1=whocares
file2=whocares2

for line in `cat $file1`
do
   for i in `grep -P "\w+ stream" $file2 | grep "$line"`   # possible but unlikely problem spot
   do
         end=$(echo $i | cut -d ' ' -f 1-4 | cut -d ',' -f 1)   # possible but unlikely spot
         duration=`testfunc $end`       # more likely problem spot
   done
done

echo "global1 = $global1"
echo "global2 = $global2"

So when I run my script, the last line says global1 = 0. However, in my function testfunc, global1 gets set to 9999 and the debug msgs print out that within the function at least, it is 9999.所以当我运行我的脚本时,最后一行说 global1 = 0。但是,在我的函数 testfunc 中,global1 被设置为 9999 并且调试消息至少在函数内打印出来,它是 9999。

Two questions here:这里有两个问题:

  1. Do the backticks spawn a subshell and thus making my script not work?反引号是否会产生一个子shell,从而使我的脚本不起作用?
  2. How do I work around this issue?我如何解决这个问题?

Do the backticks spawn a subshell and thus making my script not work? :

Yes they do and any changes made in variable in a subshell are not visible in parent shell.是的,在子 shell 中对变量所做的任何更改在父 shell 中都不可见。

How do I work around this issue?

You can probably try this loop that avoid spawning a subshell:你可以试试这个避免产生子shell的循环:

while read line
do
   while read i
   do
      end=$(echo $i | cut -d ' ' -f 1-4 | cut -d ',' -f 1)
      duration=$(testfunc "$end")
   done < <(grep -P "\w+ stream" "$file2" | grep "$line")
done < "$file1"

PS: But testfunc will still be called in sub process. PS:但是testfunc仍然会在子进程中被调用。

You can try something like你可以尝试类似的东西

global1=0
global2=0
start_read=true

function testfunc {
   global1=9999
   global2=1111
   echo "in testfunc"
   echo $global1
   echo $global2
   duration=something
}

file1=whocares
file2=whocares2

for line in `cat $file1`
do
   for i in `grep -P "\w+ stream" $file2 | grep "$line"`   # possible but unlikely problem spot
   do
         end=$(echo $i | cut -d ' ' -f 1-4 | cut -d ',' -f 1)   # possible but unlikely spot
         testfunc $end       # more likely problem spot
   done
done

echo "global1 = $global1"
echo "global2 = $global2"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM