In a different discussion on this site [see Redirecting input in a shell script] a visitor commented that “I was too busy trying to make sure the above post made sense that I forgot to ask for help. If you can, please post examples of how I can make the second argument a requirement and evaluate if it is a number. Thank you in advance!”
There are simple solutions to both issues, and I really dig into these in my popular book Wicked Cool Shell Scripts (pay special attention to script #5, validating numeric input), so I’m going to crib a bit from that script to show you how I solved this…
First off, it’s pretty easy to require a positional parameter be specified, either by checking the number of arguments given (with $#) or by simply testing the specific positional parameter for a non-null value (e.g. $2).
Really, all you do is test if it’s specified, then have whatever code subsequent that you want. In this case, I strongly suggest a “usage” message along with whatever error you’d like. In fact, my scripts almost always have a usage message with details about parameters and expected input formats if you skip any input at all.
Back to the test, though! The first test would look like this:
and the second test, if you prefer just looking at the individual parameter, would look like this:
(check the man page for ‘test’ if you want to know what the -z flag does, but if you’re writing shell scripts, it should already be something you’re familiar with. 🙂
The bigger question is how you validate for numbers only, and my general approach for testing argument value is to basically push the input through a ‘strainer’ and see what comes out the other end.
In this case, I’m going to use “sed” to replace all digits with null and see if the remainder is itself null (meaning that the argument was just digits) or not.
First step, to filter out the digits:
Now to test the result:
echo “Invalid number format! Only digits, no commas, spaces, etc.” >&2
exit 1
fi
If you want to allow negative integers, it gets a tiny bit more complicated, but you just have to test the very first character to see if it’s a minus sign, and if so, remove it. I’d suggest using “cut -c1” to get the first character, and “cut -c2-” for everything after that first digit. Something like this:
Of course, in the book I have a much fancier solution that I prefer, but it’s hard to remember when you’re whipping out a script to accomplish a specific task:
In any case, I hope that helps clarify how to both force a parameter and then test it to see if it’s a valid number or not. Oh, and in the book I have a really complicated script function that tests for valid real / floating point numbers. Considerably more complex…