2013-08-21 153 views
3

我想知道爲什麼即使使用明確的退出命令,該腳本仍會繼續運行。Bash退出不退出

我有兩個文件:

file1.txt具有以下內容:

aaaaaa 
bbbbbb 
cccccc 
dddddd 
eeeeee 
ffffff 
gggggg 

file2.txt具有以下內容:

111111 
aaaaaa 
222222 
333333 
ffffff 
444444 

腳本(test.sh)是這樣的,兩個嵌套循環檢查第一個文件的任何行是否包含第二個文件的任何行。如果發現匹配,則中止。

#!/bin/bash 
path=`dirname $0` 

cat $path/file1.txt | while read line 
do 
    echo $line 
    cat $RUTA/file2.txt | while read another 
    do 
     if [ ! -z "`echo $line | grep -i $another`" ]; then 
      echo "!!!!!!!!!!" 
      exit 0 
     fi    
    done 
done 

我得到的,即使它應該打印第一!!!!!!!!!!後退出以下的輸出:

aaaaaa 
!!!!!!!!!! 
bbbbbb 
cccccc 
dddddd 
eeeeee 
ffffff 
!!!!!!!!!! 
gggggg 

是不是exit應該徹底終結腳本的執行?

+1

我能想到的唯一原因是由於管道進入'while'。管道將爲'while'啓動另一個子進程(shell),因此'while'內的'exit'會退出該shell並返回到原始文件。 – lurker

回答

10

原因是管道創建子流程。使用輸入重定向,而不是它應該工作

#!/bin/bash 

while read -r line 
do 
    echo "$line" 
    while read -r another 
    do 
     if grep -i "$another" <<< "$line" ;then 
      echo "!!!!!!!!!!" 
      exit 0 
     fi 
    done < file2.txt 
done < file1.txt 

在一般情況下,當輸入來自另一個程序,而不是從一個文件,你可以使用process substitution

while read -r line 
do 
    echo "$line" 
    while read -r another 
    do 
     if grep -i "$another" <<< "$line" ;then 
      echo "!!!!!!!!!!" 
      exit 0 
     fi 
    done < <(command2) 
done < <(command1) 
+0

謝謝......如果不是文件,我需要比較命令的輸出呢?我怎樣才能使用輸入重定向?我嘗試過<<<命令,但它不起作用......我碰巧使用file1 file2示例來簡化問題,但我真的比較了兩個命令的輸出。 –

+0

然後你應該使用[進程替換](http://tldp.org/LDP/abs/html/process-sub.html)。例如:'while read -r line;做#命令;完成<<(其他命令)' – user000001

+0

你把我吹走了! Bash是如此的習慣。 –

3

while循環運行在它們各自的shell中。退出一個外殼不會退出包含的外殼。 $?可能是你的朋友在這裏:

  ... 
      echo "!!!!!!!!!!" 
      exit 1 
     fi 
    done 
    [ $? == 1 ] && exit 0; 
done