I have this code:
#!/bin/bash
if [ $# -lt 2 ]; then
echo "usage: $0 <-lu> <string>"
exit 1
fi
while getopts "lu" OPT
do
case $OPT in
u) casechange=0;;
l) casechange=1;;
*) echo "usage: -u<upper> || -l<lower> <string>";
exit 1;;
esac
done
shift $(( $optind -1 ))
if [ $casechange -eq 0 ]; then
tr '[A-Z]' '[a-z]' <$string
elif [ $casechange -eq 1 ]; then
tr '[a-z]' '[A-Z]' <$string
else
echo "fatal error"
exit 1
fi
I get two errors:
line 15: shift -1: shift count out of range
line 19: $string: ambiguous redirect
What am I doing wrong? How do I fix this?
OPTIND
needs to be in uppercase letters. Bash is case sensitive by default. That makes $optind
empty and you're effectively trying to shift by -1.
Also, after processing the options, you need to do something with nonoption arguments:
string="$1"
and then tr '[A-Z]' '[a-z]' <<<"$string"
for your redirects from a variable.
Lastly, your sad path outputs should be to stderr
(>&2
).
All combined (+some minor improvements):
#!/bin/bash
if [[ $# -lt 2 ]]; then
echo "usage: $0 <-lu> <string>" >&2
exit 1
fi
while getopts "lu" OPT
do
case $OPT in
u) casechange=0;;
l) casechange=1;;
*) echo "usage: -u<upper> || -l<lower> <string>" >&2;
exit 1;;
esac
done
shift $(( $OPTIND -1 ))
string="$1"
if [[ "$casechange" -eq 0 ]]; then
tr 'A-Z' 'a-z' <<<"$string"
elif [[ "$casechange" -eq 1 ]]; then
tr 'a-z' 'A-Z' <<<"$string"
else
echo "fatal error" >&2
exit 1
fi