2014-01-08 82 views
9

我對函數,變量作用域和可能的子殼有點困惑。 我在另一個post中看到管道產生了一個子shell,並且父shell無法從子shell訪問變量。反斜槓上的cmds也是這種情況嗎?腳本中的bash shell腳本和函數的變量範圍

爲了不傷害人,我縮短了我的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. 我該如何解決這個問題?

在此先感謝您的幫助。

+1

1.是的,他們做2.快速修復:刪除反引號和移動函數定義的分配。或者寫global1 ='testfunc $ end' – damienfrancois

+0

順便說一下,那些嵌套的'for'循環看起來真的是扭曲和效率低下的。我想你正在試圖說'grep -P「\ w + stream」「$ file2」| grep -f「$ file1」|同時閱讀我;做'... – tripleee

+0

@damienfrancois,thx爲您的答覆。 testfunc修改了幾個全局變量。我想這是我忘了包括的一件事。 – Classified

回答

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" 
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仍將在子過程調用。