2012-07-23 4 views
1

Bash 스크립트에 이상한 문제가 있습니다. 변수 NumTMPara은 내부 루프 내부에 올바른 값을 가지고 있지만 루프 외부에서는 값이 0입니까? 이 때까지변수가 루프 외부에서 정의되지 않았습니다.

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 

...

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 

모든 것이 괜찮 :

10512 YCSR271B 0 

왜 0 여기

내 스크립트입니다?

+0

OMG, 서식을 수정하십시오. – KurzedMetal

+0

탭을 세미콜론으로 대체 할 필요가 없습니다.'cut -d $ '\ t'-f2'는 탭에서 직접 작동합니다. – chepner

+0

@chepner : 탭은 기본 구분자이므로 'cut -f2'이면 충분합니다. – ruakh

답변

3

파이프 라인 (command1 | command2 | command3)에서 각 명령은 별도의 서브 쉘에서 실행되는 것이 문제입니다. 즉, 기본 셸의 모든 변수가 각 명령의 실행 환경으로 복사되지만 명령이 변경하면 주 셸의 실행 환경으로 다시 복사되지 않습니다.

당신은 몇 가지 옵션이

하지만, 두 가지 주요 것들 :

  • 변수가 하지을 수 있도록 당신은 당신의 스크립트를 재구성 할 수는 파이프 라인 내부에 할당된다.
    • 예를 들어 command1 | command2 | while ... do ... done 대신 while ... do ... done < <(command1 | command2)을 쓸 수 있습니다. 서브 쉘에는 여전히 command1command2이 실행되지만, while -loop은 필요한만큼 주 쉘에서 실행됩니다.
  • 파이프 라인이 완료된 후에 읽을 수있는 임시 파일에 변수를 저장할 수 있습니다.
+0

그것이 작동합니다! 고맙습니다 ! 이 구문에 대한 정보를 어디에서 얻을 수 있는지 알고 있습니까? – user1546581

+0

@ user1546581 :'<(command)'표기법은 * process substitution *이라 불리우며 * Bash Reference Manual *의 §3.5.6 "Process Substitution"(http://www.gnu.org)에 문서화되어 있습니다. /software/bash/manual/bashref.html#Process-Substitution). 그러나 나는 대체 입력의 출력을 대체하기 위해'<<(command) '를 쓸 수 있다는 사실을 본 적이 없다. StackOverflow에 대한 언급에서 누군가가 한 번 언급했기 때문에 나는 그것을 안다. – ruakh

관련 문제