while [ $# -gt 0 ]; do
case "$1" in
--from*|-f*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local FROM="${1#*=}"
;;
--to*|-t*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local TO="${1#*=}"
;;
--file*|-z*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local SINGLEFILE="${1#*=}"
;;
--help|-h)
doc_convert_usage
return;
;;
*)
>&2 printf "Error: Invalid argument\n"
return;
;;
esac
shift
done
What does this code do?
- First we are grabbing the positional parameters
- Then we loop through each parameters and pass them through a case statement
- Depending on what we pass in we will be able to check for a named argument or an abbreviated version using the pipe symbol
--from*|-f*)
. - In each case we check if an equals sign was used. This gives us the ability to pass in arguments as
myfunction arg1=somevalue1
or asmyfunction arg1 somevalue1
.
We get the best of both worlds for passing in values to our shell scripts.
Example in context
Here is a full example I’ve used in the past to show the above code in context of a full function. This is the function I use to quickly convert word documents into pdfs through the command line.
doc_convert_usage() {
echo "doc_convert -f docx -t pdf"
echo "-f\t from\t default=docx|doc\t The file type you are wanting to convert"
echo "-t\t to\t default=pdf\t\t The file type you are converting to"
echo "-z\t file\t default=none\t\t Use to target a single"
}
doc_convert() {
command -v soffice >/dev/null 2>&1 || { echo "Install LibreOffice and add soffice to your path. Aborting." >&2; return; }
command -v greadlink >/dev/null 2>&1 || { echo "You need coreutils, instal with: brew install coreutils. Aborting." >&2; return; }
while [ $# -gt 0 ]; do
case "$1" in
--from*|-f*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local FROM="${1#*=}"
;;
--to*|-t*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local TO="${1#*=}"
;;
--file*|-z*)
if [[ "$1" != *=* ]]; then shift; fi # Value is next arg if no `=`
local SINGLEFILE="${1#*=}"
;;
--help|-h)
doc_convert_usage
return;
;;
*)
>&2 printf "Error: Invalid argument\n"
return;
;;
esac
shift
done
if [ -z "${FROM}" ]; then
local FROM="docx|doc"
fi
if [ -z "${TO}" ]; then
local TO="pdf"
fi
echo "\n**************************\n"
echo "You are about to convert \"${FROM}\" files to \"${TO}\":";
local PERMISSONTOCHANGEFILES
vared -p "Convert? (y/n): " -c PERMISSONTOCHANGEFILES
if [[ "$PERMISSONTOCHANGEFILES" == "y" ]]; then
if [ -z "${SINGLEFILE}" ]; then
for DOCUMENT in $(find -E . -type f -iregex ".*\.(${FROM})$")
do
local FILE=$(greadlink -f "${DOCUMENT}")
local FILEURL=$(dirname "${FILE}")
soffice --headless --convert-to "${TO}" "${DOCUMENT}" --outdir "${FILEURL}"
done
else
soffice --headless --convert-to "${TO}" "${SINGLEFILE}"
fi
else
echo "\nNothing has been converted\n"
fi
return;
}