Bash Script Function Return True-False
Solution 1
true
and false
are commands that exit with success and failure exit codes, respectively. They do not make your function return those values, to do that use the return
command, and integer values corresponding to success (0) or failure (anything other than 0). Also, I'm pretty sure you don't want to return failure for the first line that doesn't match, just if no line matched:
check(){
file=/root/Turkiye.txt
local funkx=$1
while read line; do
if [ "$line" == "$funkx" ]
then
return 0 # 0 = success ("true"); break is not needed because return exits the function
fi
done < $file
# If a line matched, it won't get here (it will have returned out of the middle
# of the loop). Therefore, if it gets here, there must not have been a match.
return 1 # 1 = failure ("false")
}
But there's a much simpler way to do this. Use grep
-- its job is to search files for matching lines. You want grep -Fxq
-- -F
means search for fixed strings (not regular expression patterns), -x
means require the whole line to match, not just part of it, and -q
means don't bother printing the result, just exit with success status if a match was found, failure otherwise. And you don't even need an explicit return
command, since the function will implicitly return the status of the last command in it:
check(){
file=/root/Turkiye.txt
local funkx=$1
grep -Fxq "$funkx" "$file"
}
Or even simpler:
check(){
grep -Fxq "$1" /root/Turkiye.txt
}
Solution 2
Testing your code on another file, it does actually work, even if it's a bit inefficient. Assuming that the /root/Turkiye.txt
file is a non-empty file that you have access to, the true
and false
calls, since they are the last commands to be executed in the function, sets the exit status of the function to either zero or non-zero.
It may simply be that you are entering strings into your script that can't be found as separate lines in the file you are reading. It's unfortunately unclear in the question what the file you are parsing looks like, what you are entering into your script and what you expect to get as a response from the script when doing so.
Note also that while read line
does not necessarily read lines from the input file. See e.g. "Understanding "IFS= read -r line"", and also that within [ ... ]
the operator that compares two strings is =
, not ==
.
You also need to double quote $keyboard
in your call to check
to avoid word splitting and filename generation (globbing).
It seems as if you want to use your function to determine whether the string read from the user occurs as a line in a particular file.
This could be done easier with
grep -qxF -e "$keyboard" /root/Turkiye.txt
This grep
command would search for the string in the given file and return a zero exit status (true) if a line is found that is exactly identical, and will otherwise return a non-zero exit status (false). The options used here are -q
to make grep
not output anything, -x
to compare full lines (not substrings) and -F
to do string comparisons (not regular expression matching). The -e
tells grep
that the next argument is the search pattern (an initial -
in the pattern would otherwise have been taken as introducing a command line option).
Your script, modified:
printf 'Please enter the value: ' >&2
IFS= read -r keyboard
if grep -qxF -e "$keyboard" /root/Turkiye.txt; then
echo 'yes'
else
echo 'no'
fi
Note that I output the prompt for the user to enter a string to the standard error stream. This is by convention and allows the output of the script to be redirected and used without it containing the prompt.
In bash
, you would have used
IFS= read -r -p 'Please enter the value: ' keyboard
(Note that bash
would output the prompt string to the standard error stream too when you use read -p
.)
If you would want to use the grep
in a function:
check () {
grep -qxF -e "$1" /root/Turkiye.txt
}
Then use
if check "$keyboard"; then
echo 'yes'
else
echo 'no'
fi
Related videos on Youtube
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on September 18, 2022Comments
-
Admin almost 2 years
I want to query the function by returning the value. My codes are as follows;
check(){ file=/root/Turkiye.txt local funkx=$1 while read line; do if [ "$line" == "$funkx" ] then true break else false fi done < $file } printf "Please enter the value : " read keyboard if check $keyboard; then echo "yes"; else echo "no"; fi
It does not work, what am I doing wrong?
-
D. Ben Knoble over 5 yearsTechnically
true; return
andfalse; return
work:return
defaults to the last exit code$?
-
javaamtho over 5 years@D.BenKnoble You're correct, but the original script does something much less obvious than that. In fact, you could remove the
true
andfalse
commands (or reverse them) in the original script and it wouldn't change the results. That's because if a line matches, it executestrue
, and thenbreak
, so the return status is from thebreak
command (which will be 0). Similarly, if no match is found the last command executed is the loop test,read line
(which will be 1). So it actually gets the right results, but not for reasonable reasons.