Variable scope for bash shell scripts and functions in the script

13,830

Solution 1

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"

Solution 2

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.

How do I work around this issue?

You can probably try this loop that avoid spawning a subshell:

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.

Share:
13,830

Related videos on Youtube

Classified
Author by

Classified

Updated on September 19, 2022

Comments

  • Classified
    Classified over 1 year

    I'm a little confused with my script regarding functions, variable scope, and possibly subshells. 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?

    To not bore people, I've shortened my 100+ line script but I tried to remember to leave in the important elements (i.e. backticks, pipes etc). 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.

    Two questions here:

    1. Do the backticks spawn a subshell and thus making my script not work?
    2. How do I work around this issue?
    • damienfrancois
      damienfrancois over 10 years
      1. Yes they do 2. Quick fix: remove the backticks and move the assignment in the function definition. Alternatively write global1= ` testfunc $end `
  • myrdd
    myrdd over 5 years
    Difference to the script of the OP: (1) duration=something has been added to the function body; (2) duration=`testfunc $end` in the loop has been changed to testfunc $end