Reputation: 1185
I'm writing a simple shell script that should exit with 0 if an input string is found in a file, and exit with 1 if it isn't
INPSTR=$1
cat ~/file.txt | while read line
do
if [[ $line == *$INPSTR* ]]; then
exit 0
fi
done
#string not found
exit 1
What's actually happening is that when the string is found, the loop exits, and the shell then goes to "exit 1". What's the correct way to exit from the shell script entirely while in a loop?
Upvotes: 20
Views: 12523
Reputation: 51
One of the other ways would be to put most of your code in function and use return
. This would probably look somehow like this:
#!/bin/bash
isTextInFile() {
local needle="$1"
cat ~/file.txt | while read line
do
if [[ $line == *$needle* ]]; then
return 0
fi
done
#string not found
return 1
}
isTextInFile "$1"
exit
return
will break both the loop, the subshell (introduced by using the pipe |
usage, as other comments and answers mention) and the whole function.
Last exit
without parameters will use code returned from the function.
Added bonus, your code could be made reusable with some more extra effort.
Upvotes: 0
Reputation: 41
For those who are looking for real variant for exit without double check in and after loop. I came up for simular task. To exit from whole script we can kill its task by pid. But need to get pid very carefully so not killing some important parent-parent id. The pid of loop must be $BASHPID, and the ppid (pid of script) will be $$ (if no more subshells used) So in this case command is
kill -9 $$
or if your shell child survives after killing parent it can be
kill -9 $$ $BASHPID
Upvotes: 0
Reputation: 101
you can catch return code of subshell using $? like this
INPSTR=$1
cat ~/file.txt | while read line
do
if [[ $line == *$INPSTR* ]]; then
exit 0
fi
done
if [[ $? -eq 0 ]]; then
exit 0
else
#string not found
exit 1
fi
Upvotes: 10
Reputation: 785146
You need to avoid creating sub-shell in your script by avoiding the pipe and un-necessary cat
:
INPSTR="$1"
while read -r line
do
if [[ $line == *"$INPSTR"* ]]; then
exit 0
fi
done < ~/file.txt
#string not found
exit 1
Otherwise exit 0
is only exiting from the sub-shell created by pipe and later when loop ends then exit 1
is used from parent shell.
Upvotes: 14