Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bourne Shell exit will not work

Tags:

shell

sh

exit

I have the following script

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

everything works up to echo and then when the script hits exit it does not and keeps going. Any ideas.

Thanks

like image 721
user174084 Avatar asked Dec 02 '25 21:12

user174084


1 Answers

You don't need that backslash - this is not the C shell.

The problem is that the while loop is in a sub-shell, which exits, but because it is run as a sub-shell, the main script continues.

In the context, the simplest fix is probably:

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

If you have to process multiple files ('cat "$@"' instead of 'cat $1'), then you have to work a lot harder bit harder:

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

This checks the exit status of the pipeline consisting of 'cat' and 'while', which is the exit status of the 'while' loop, which will be 1 in the example if 'foo:bar' is found at the start of a line.

Of course, there are other ways to detect that, such as:

grep -s -q "^foo:bar:" "$@" && exit 1

This executes a lot less commands than the loop version. (If you need to allow for '^foo:bar$' as well, use egrep instead of plain grep.)

like image 70
Jonathan Leffler Avatar answered Dec 04 '25 16:12

Jonathan Leffler