Выход из Bourne Shell не получится
Вопрос
У меня есть следующий скрипт
cat $1 | while read line
do
line=`echo $line | tr "[:lower:]" "[:upper:]"`
if [ "`echo $line | cut -f1 -d:`" = "foo" ] && \
[ "`echo $line | cut -f2 -d:`" = "bar" ]; then
echo 'exsist'
exit 1;
fi
done
все работает до эха, а затем, когда сценарий достигает выхода, он не работает и продолжает работать.Есть идеи.
Спасибо
Решение
Вам не нужна обратная косая черта — это не оболочка C.
Проблема в том, что цикл while находится во вложенной оболочке, которая завершается, но поскольку он запускается как вложенная оболочка, основной сценарий продолжает выполняться.
В контексте, вероятно, самое простое решение:
while read line
do
line=`echo $line | tr "[:lower:]" "[:upper:]"`
if [ "`echo $line | cut -f1 -d:`" = "foo" ] &&
[ "`echo $line | cut -f2 -d:`" = "bar" ]; then
echo 'exist'
exit 1
fi
done < $1
Если вам нужно обработать несколько файлов («cat «$@»» вместо «cat $1»), вам придется работать намного сложнее немного сложнее:
cat "$@" |
while read line
do
line=`echo $line | tr "[:lower:]" "[:upper:]"`
if [ "`echo $line | cut -f1 -d:`" = "foo" ] &&
[ "`echo $line | cut -f2 -d:`" = "bar" ]; then
echo 'exist'
exit 1
fi
done
[ $? != 0 ] && exit 1
Это проверяет статус завершения конвейера, состоящего из «cat» и « while», который является статусом завершения цикла while, который в примере будет равен 1, если «foo:bar» найден в начале линия.
Конечно, есть и другие способы обнаружить это, например:
grep -s -q "^foo:bar:" "$@" && exit 1
При этом выполняется гораздо меньше команд, чем в версии с циклом.(Если вам также необходимо разрешить использование '^foo:bar$', используйте egrep вместо обычного grep.)
Другие советы
Вы переводите свой текст из нижнего регистра в верхний регистр, но затем проверяете его на нижний регистр, поэтому вы никогда не доберетесь до выхода.
поскольку вы хотите преобразовать каждую строку в верхний регистр, вы можете сделать это следующим образом
#!/bin/sh
tr '[:lower:]' '[:upper:]' < file | while IFS=":" read -r a b c
do
case "$a $b" in
"FOO BAR" ) echo "exist";exit;;
*) echo "$a $b";;
esac
done
ИЛИ вы можете сделать это с помощью awk (nawk для Solaris)
nawk -F":" '
topper($1)=="FOO" && topper($2)=="BAR"{
print "exist"
exit
}
{
print topper($0)
}
' file
Вы можете сделать свои условия нечувствительными к регистру, добавив shopt -s nocasematch
выше теста.Чтобы вернуть значение с учетом регистра: shopt -u nocasematch
.