We've done a lot of checks in the book so far. One we haven't carried out, however, is on the length of the supplied parameter. What will probably not surprise you at this point is how we can achieve this: with parameter expansion, of course. The syntax is really simple, too:
Parameter length. The length in characters of the value of parameter is substituted. If parameter is * or @, the value substituted is the number of positional parameters.
So, instead of printing ${variable}, which will substitute the value at runtime, we will use ${#variable}, which will give us a number: the number of characters in our value. This might be a little tricky, as things such as whitespaces can also be considered characters.
Take a look at the following example:
reader@ubuntu:~/scripts/chapter_16$ variable="hello"
reader@ubuntu:~/scripts/chapter_16$ echo ${#variable}
5
reader@ubuntu:~/scripts/chapter_16$ variable="hello there"
reader@ubuntu:~/scripts/chapter_16$ echo ${#variable}
11
As you can see, the word hello is identified as five characters; so far, so good. When we look at the sentence hello there, we can see two words of five letters each. While you might expect the parameter expansion to return 10, it actually returns 11. Since the words are separated by a space, you should not be surprised: this space is the 11th character.
If we take a look back at the syntax definition from the man bash page, we'll see the following interesting tidbit:
Remember how we used $# to determine how many arguments are passed to the script in the rest of this book? This is actually Bash parameter expansion at work, as ${#*} is equal to $#!
To drive these points home, let's create a quick script that deals with three-letter acronyms (our personal favorite type of acronym). For now, the functionality of this script will be limited to verifying and printing the user input, but when we get to the end of this chapter, we'll amend it a bit to make it even cooler:
reader@ubuntu:~/scripts/chapter_16$ vim acronyms.sh
reader@ubuntu:~/scripts/chapter_16$ cat acronyms.sh
#!/bin/bash
#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-12-16
# Description: Verify argument length.
# Usage: ./acronyms.sh <three-letter-acronym>
#####################################
# Use full syntax for passed arguments check.
if [[ ${#*} -ne 1 ]]; then
echo "Incorrect number of arguments!"
echo "Usage: $0 <three-letter-acronym>"
exit 1
fi
acronym=$1 # No need to default anything because of the check above.
# Check acronym length using parameter expansion.
if [[ ${#acronym} -ne 3 ]]; then
echo "Acronym should be exactly three letters!"
exit 2
fi
# All checks passed, we should be good.
echo "Your chosen three letter acronym is: ${acronym}. Nice!"
We did two interesting things in this script: we used the full syntax of ${#*} to determine the number of arguments passed to our script, and we checked the acronym length with ${#acronym}. Because we used two different checks, we used two different exit codes: exit 1 for the wrong number of arguments, and exit 2 for incorrect acronym length.
In larger, more complex scripts, using different exit codes might save you a significant amount of troubleshooting, so we've included it here for information.
If we now run our script with different incorrect and correct input, we can see it works as planned:
reader@ubuntu:~/scripts/chapter_16$ bash acronyms.sh
Incorrect number of arguments!
Usage: acronyms.sh <three-letter-acronym>
reader@ubuntu:~/scripts/chapter_16$ bash acronyms.sh SQL
Your chosen three letter acronym is: SQL. Nice!
reader@ubuntu:~/scripts/chapter_16$ bash acronyms.sh SQL DBA
Incorrect number of arguments!
Usage: acronyms.sh <three-letter-acronym>
reader@ubuntu:~/scripts/chapter_16$ bash acronyms.sh TARDIS
Acronym should be exactly three letters
No arguments, too many arguments, arguments of incorrect length: we're equipped to handle everything the user might throw at us. As always, never expect the user to do what you hope, just ensure your script will only execute if the input is correct!