I am trying to make script that has two switches -h and -d, -d having a mandatory number argument. After it there will be undetermined number of paths to file. So far, I have this, but the code seems to not recognize invalid switch -r (can be any name) and also does not work when I do not input any switches:
while getopts ":hd:" opt; do
case $opt in
h)
echo $usage
exit 0
;;
d)
shift 2
if [ "$OPTARG" -eq "$OPTARG" ] ; then # ako dalsi argument mame cislo
depth=$OPTARG
fi
;;
\?)
shift 1
;;
:)
shift 1
;;
esac
done
echo $1
when I type ./pripravne1.sh -d /home/OS/test_pz/test2
I get ./pripravne1.sh: [: /home/OS/test_pz/test2: integer expression expected
when I type ./pripravne1.sh -r /home/OS/test_pz/test2
I get only empty string.
[
being not a special it would not exit the shell.[
would return a non-zero exit status and output an error message if it didn't like an operand to-eq
. POSIX says operands are to be decimal integer numbers but doesn't say what should happen if one passes operands that are not, and the behaviour varies between implementation. For instance, withOPTARG='x[$(reboot)]'
, in ksh,[ "$OPTARG" -eq "$OPTARG" ]
would return true (assuming$x
is unset or not things likenan
,RANDOM
,++y
...) and... reboot. – Stéphane Chazelas Oct 29 '18 at 18:44shift
inside thewhile getopts
loop.getopts
takes care of stepping through the arguments itself, and if you change the arg list out from under it, things will get very confused. Instead, wait 'till after the loop, and then runshift "$((OPTIND - 1))"
to remove all options from the arg list at once. – Gordon Davisson Oct 29 '18 at 18:49shift 2
in the code for-d
, something like-d 1 -d 2 -d 3
would result in the code only seeing-d 1
and-d 3
, the-d 2
being shifted away in between. – ilkkachu Oct 29 '18 at 21:21dash
seems to be the only shell that handles well (ie the way I naively expect it) the arg list being changed from underneathgetopts
(either withshift
or withset -- ...
). – Oct 31 '18 at 21:15