Yes-no check

We'll show one more check before we finish this chapter. Halfway through the book, in Chapter 9, Error Checking and Handling, we presented a script that dealt with a user that could supply either a 'yes' or a 'no'. But, as we explained there, the user might also use 'y' or 'n', and perhaps even a capital letter in there somewhere. By secretly using a little Bash expansion, which you will see properly explained in Chapter 16, Bash Parameter Substitution and Expansion, we were able to make a relatively clear check for user input. Let's get that thing in our library!

reader@ubuntu:~/scripts/chapter_13$ vim ~/bash-function-library.sh 
reader@ubuntu:~/scripts/chapter_13$ cat ~/bash-function-library.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.3.0
# Date: 2018-11-17
# Description: Bash function library.
# Usage: source ~/bash-function-library.sh
#####################################
<SNIPPED>

# Checks if the user answered yes or no.
check_yes_no() {
# Input validation.
if [[ $# -ne 1 ]]; then
echo "Need exactly one argument, exiting."
exit 1 # No validation done, exit script.
fi

# Return 0 for yes, 1 for no, exit 2 for neither.
if [[ ${1,,} = 'y' || ${1,,} = 'yes' ]]; then
return 0
elif [[ ${1,,} = 'n' || ${1,,} = 'no' ]]; then
return 1
else
echo "Neither yes or no, exiting."
exit 2
fi
}

We've got a little advanced scripting cooked up for you with this example. Instead of a binary return, we now have four possible outcomes:

  • Function incorrectly called: exit 1
  • Function found a yes: return 0
  • Function found a no: return 1
  • Function found neither: exit 2

With our new library function, we'll take the yes-no-optimized.sh script and replace the complex logic with (almost) a single function call:

reader@ubuntu:~/scripts/chapter_13$ cp ../chapter_09/yes-no-optimized.sh library-yes-no.sh
reader@ubuntu:~/scripts/chapter_13$ vim library-yes-no.sh
reader@ubuntu:~/scripts/chapter_13$ cat library-yes-no.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-11-17
# Description: Doing yes-no questions from our library.
# Usage: ./library-yes-no.sh
#####################################

# Load our Bash function library.
source ~/bash-function-library.sh

read -p "Do you like this question? " reply_variable

check_yes_no ${reply_variable} &&
echo "Great, I worked really hard on it!" ||
echo "You did not? But I worked so hard on it!"

Take a minute to look at the preceding script. It will probably be a little confusing at first, but try to remember what && and || do. Because of some smart ordering we applied, we can use && and || in sequence to achieve our result. Look at it like this:

  1. If check_yes_no returns an exit status of 0 (when a yes is found), the command after && is executed. Since that echoes the success, and echo has an exit code of 0, the failure echo after the next || is not executed.
  2. If check_yes_no returns an exit status of 1 (when a no is found), the command after && is not executed. However, it continues until it reaches ||, which goes on to the failure echo since the return code was still not 0.
  3. If check_yes_no exits on either the lack of argument or lack of yes/no, the commands after both && and || are not executed (because the script is given an exit instead of return, so code execution is stopped immediately).

Pretty clever right? However, we must admit, it's a little against most things we've been teaching you with regards to readability. Consider this a teaching exercise for chaining && and || instead. If you'd want to implement the yes-no check yourself, it would probably be better to create dedicated check_yes() and check_no() functions. In any case, let's see if our tricked out script actually works as we hope it does:

reader@ubuntu:~/scripts/chapter_13$ bash library-yes-no.sh 
Do you like this question? Yes
Great, I worked really hard on it!
reader@ubuntu:~/scripts/chapter_13$ bash library-yes-no.sh
Do you like this question? n
You did not? But I worked so hard on it!
reader@ubuntu:~/scripts/chapter_13$ bash library-yes-no.sh
Do you like this question? MAYBE
Neither yes or no, exiting.
reader@ubuntu:~/scripts/chapter_13$ bash library-yes-no.sh
Do you like this question?
Need exactly one argument, exiting.

All scenarios as we've defined them in the check work out. Great success!

Normally, you do not want to mix exit and return codes too much. Also, using a return code to convey anything other than pass or fail is also pretty uncommon. However, since you can return 256 different codes (from 0 up to 255), this is at least possible by design. Our yes-no example was a good candidate for showing how this could be used. However, as a general tip, you're probably better off by using it in a pass/fail way, as currently you place the burden of knowing the different return codes on the caller. Which is, to say the least, not always a fair thing to ask of them.

We'd like to end this chapter with a small exercise for you. In this chapter, before we introduced the function library, we already created a few functions: two for error handling, one for colored printing, and one for reversing text. Your exercise is simple: grab those functions and add them to your personal function library. Make sure to keep the following things in mind:

  • Are the functions verbose enough to be included in the library as is, or could they use more?
  • Can we call the functions and deal with the output as is, or would an edit be preferable?
  • Are returns and exits properly implemented, or do they need to be adjusted to work as a generic library function?

There are no right or wrong answers here, just things to consider. Good luck!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.52.88