Выход 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 не должно полностью завершать выполнение скрипта?


person Tulains Córdova    schedule 21.08.2013    source источник
comment
Единственная причина, о которой я могу думать, связана с каналом в while. Канал запускает другой подпроцесс (оболочку) для while, поэтому exit внутри while выходит из этой оболочки, а вы возвращаетесь к исходному.   -  person lurker    schedule 21.08.2013


Ответы (2)


Причина в том, что каналы создают подпроцессы. Вместо этого используйте перенаправление ввода, и оно должно работать

#!/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)
person user000001    schedule 21.08.2013
comment
Спасибо... Что, если вместо файлов мне нужно сравнить вывод слишком команд? Как я могу использовать перенаправление ввода с этим? Я попробовал команду ‹‹‹, но она не сработала... Я использовал пример file1 file2, чтобы упростить вопрос, но на самом деле я сравниваю вывод двух команд. - person Tulains Córdova; 21.08.2013
comment
Затем вам следует использовать подстановку процессов. Например: while read -r line; do #commands; done < <(othercommand) - person user000001; 21.08.2013
comment
Ты поразил меня! Баш такой идиоматический. - person Tulains Córdova; 21.08.2013
comment
Мне так помогло! Приснился кошачий файл | к циклу while, и он просто не хотел выходить из скрипта. Он выйдет только из цикла. Переключился на перенаправление ввода, и выход сработал. Спасибо! - person Nick Constantine; 06.12.2017

Циклы while выполняются в соответствующих оболочках. Выход из одной оболочки не приводит к выходу из содержащих ее. $? может быть твоим другом здесь:

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