Bash退出不退出

15

我想知道为什么这个脚本即使有明确的退出命令仍然继续运行。

我有两个文件:

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
2个回答

19

原因是管道会创建子进程。改用输入重定向,就可以解决此问题。

#!/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

一般情况下,如果输入不是来自文件而是另一个程序,您可以使用进程替换

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)

1
谢谢...如果我需要比较两个命令的输出,而不是文件,该怎么办?我该如何使用输入重定向?我尝试过<<<命令,但它没有起作用...我之前使用file1 file2的例子只是为了简化问题,实际上我是在比较两个命令的输出。 - Tulains Córdova
然后你应该使用进程替换。例如:while read -r line; do #commands; done < <(othercommand) - user000001
你让我大吃一惊!Bash 如此地惯用。 - Tulains Córdova
2
帮助了我很多!我有一个 cat 文件 | 放到 while 循环中,但它就是不想退出脚本。它只会退出循环。切换到输入重定向后,退出功能正常了。感谢! - Nick Constantine

6

while循环在各自的shell中运行。退出一个shell不会退出包含它的shell。在这里,$?可能是你的朋友:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接