2012-07-23 109 views
1

我有一個奇怪的問題與Bash腳本。變量NumTMPara在內部循環中有正確的值,但在循環外部,值爲0?變量undefined在循環外部

這裏是我的腳本:

echo "packet.txt" 
cat $SRDB_dir/tpcf.dat | sed -e 's/[\t]/;/g' \ 
| while read my_line 
    do 
    PID_SPID=$(echo $my_line | cut -f1 -d';') 
    TPCF_NAME=$(echo $my_line | cut -f2 -d';') 
    NumTMPara=0 
    cat $SRDB_dir/plf.dat | sed -e 's/[\t]/;/g' | grep ";$PID_SPID;" \ 
    | while read my_line2 
     do 
     PCF_NAME=$(echo $my_line2 | cut -f1 -d';') 
     Param_ID=$(cat $destination/tmparam.txt | sed -e 's/[\t]/;/g' | grep ";$PCF_NAME," | cut -f1 -d ';') 
     OFFBYTE=$(echo $my_line2 | cut -f3 -d';') 
     OFFBIT=$(echo $my_line2 | cut -f4 -d';') 

     Myptc=$(grep $PCF_NAME $SRDB_dir/pcf.dat | sed -e 's/[\t]/;/g' | cut -f5 -d';') 
     Mypfc=$(grep $PCF_NAME $SRDB_dir/pcf.dat | sed -e 's/[\t]/;/g' | cut -f6 -d';') 
     WIDTH=$(get_width $Myptc $Mypfc) 

     PCF_RELATED="" 
     PCF_DESCR=$(grep "^$PCF_NAME" $SRDB_dir/pcf.dat | sed -e 's/[\t]/;/g' | cut -f2 -d ';') 
     let NumTMPara=1+${NumTMPara} 

     #here, the value is correctly reported 
     echo -e "\t$PCF_NAME\t$Param_ID\t$OFFBYTE\t$OFFBIT\t$WIDTH\t$PCF_RELATED\t$PCF_DESCR \t${NumTMPara}" 
     packetligne="\t$PCF_NAME\t$Param_ID\t$OFFBYTE\t$OFFBIT\t$WIDTH\t$PCF_RELATED\t$PCF_DESCR" 
     done 

    #Why does NumTMPara = 0 ?? 
    echo -e "$PID_SPID\t$TPCF_NAME\t${NumTMPara}" 
    done 

一切都很好...

NCGT0030 14189 16 0 16 TC Packet ID 1 
NCGT0040 14190 18 0 16 TC Packet Seq Control 2 
NCGT0020 14188 20 0 16 Generic Failure ID 3 
NCGB00B4 14074 22 0 32 Data Field Header 4 

直到這個:

10512 YCSR271B 0 

爲什麼0?

+0

OMG,請修復格式。 – KurzedMetal 2012-07-23 18:17:17

+0

您不需要用分號替換標籤:'cut -d $'\ t'-f2'將直接在標籤上工作。 – chepner 2012-07-23 19:08:23

+0

@chepner:無論如何,標籤是默認的分隔符,所以'cut -f2'就足夠了。 – ruakh 2012-07-23 19:09:19

回答

3

問題是,在流水線(command1 | command2 | command3)中,每個命令都在單獨的子shell中運行。這意味着主shell中的任何變量都被複制到每個命令的執行環境中,但是該命令所做的任何更改都不會被複制回主shell的執行環境中。

您有幾種選擇,但有兩個主要的:

  • 你可以調整你的腳本,以便變量是被分配管線內部。
    • 例如,您可以編寫while ... do ... done < <(command1 | command2)而不是command1 | command2 | while ... do ... done。這仍然會在子shell中運行command1command2,但while -loop將根據需要在主shell中運行。
  • 您可以將該變量保存到管道完成後您可以讀取的臨時文件中。
+0

它的工作原理!謝謝 !你知道我可以從哪裏得到關於這個語法的信息嗎? – user1546581 2012-07-24 08:08:55

+0

@ user1546581:'<(command)'符號被稱爲*進程替換*,並記錄在* Bash參考手冊的§3.5.6「進程替換」中(http://www.gnu.org) /software/bash/manual/bashref.html#Process-Substitution)。然而,我從來沒有見過這樣一個事實的文檔,你可以寫'<(command)'來從標準輸入中取代替代進程的輸出。我只知道它,因爲我看到有人在StackOverflow的評論中提到過它。 – ruakh 2012-07-24 13:29:13