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

Linux bash shell脚本和脚本中函数的变量范围,linux,bash,shell,unix,Linux,Bash,Shell,Unix,关于函数、变量范围和可能的子shell,我对我的脚本有点困惑。 我在另一个例子中看到,管道生成子shell,父shell无法从子shell访问变量。CMD在backticks中运行时也是这种情况吗 为了不让人厌烦,我缩短了100多行的脚本,但我试着记住在重要的元素(如回击、管道等)中留下。希望我没有遗漏什么 global1=0 global2=0 start_read=true function testfunc { global1=9999 global2=1111 ech

关于函数、变量范围和可能的子shell,我对我的脚本有点困惑。 我在另一个例子中看到,管道生成子shell,父shell无法从子shell访问变量。CMD在backticks中运行时也是这种情况吗

为了不让人厌烦,我缩短了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,调试msgs打印出函数中至少是9999

这里有两个问题:

  • backticks是否会生成一个子shell,从而使我的脚本 工作
  • 我如何解决这个问题
  • 反勾号是否会产生子shell,从而使我的脚本无法工作?

    是的,在子shell中对变量所做的任何更改在父shell中都不可见

    我如何解决这个问题?

    您可能可以尝试此循环以避免生成子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"
    
    读取行时
    做
    当我读书的时候
    做
    结束=$(回显$i |切-d'-f 1-4 |切-d','-f 1)
    持续时间=$(testfunc“$end”)
    
    完成<您可以尝试以下方法

    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"
    

    1.是的,他们有两个。快速修复:删除反勾号并在函数定义中移动赋值。或者写global1=`testfunc$end`作为旁白,那些嵌套的
    for
    循环看起来非常扭曲和低效。我猜你在读I时想说
    grep-P”\w+stream“$file2”| grep-f“$file1”;请务必
    …@damienfrancois,谢谢您的回复。testfunc修改几个全局变量。我想这是我忘了包括的一件事。好的,那么您可以尝试用简单的
    testfunc$end
    替换
    duration=`testfunc$end`
    ,并在函数体中添加
    duration=…
    。你可以把bash函数想象成一个简单的内联扩展的宏。与OP脚本的不同之处在于:(1)
    duration=something
    已添加到函数体中;(2) 循环中的
    duration=`testfunc$end`
    已更改为
    testfunc$end