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

时间:2014-01-08 21:15:13

标签: linux bash shell unix

我对我的脚本关于函数,变量范围和可能的子shell有点困惑。 我在另一个post中看到管道产生子shell,而父shell无法从子shell中访问变量。这也是cmt在反引号中运行的情况相同吗?

为了不让人厌烦,我缩短了我的100多行剧本,但我试图记住留下重要元素(即反引号,管道等)。希望我没有遗漏任何东西。

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"

所以当我运行我的脚本时,最后一行表示global1 = 0.但是,在我的函数testfunc中,global1设置为9999并且调试消息打印出函数内至少为9999.

这里有两个问题:

  1. 反引号会产生一个子shell,从而使我的脚本没有 工作?
  2. 如何解决此问题?
  3. 提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

  

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

是的,他们这样做,并且子shell中的变量中所做的任何更改在父shell中都不可见。

  

How do I work around this issue?

您可以尝试使用此循环来避免产生子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:但仍会在子流程中调用testfunc

答案 1 :(得分:2)

您可以尝试类似

的内容
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"