Here is my script:
#!/bin/ksh
usage ()
{
echo " Usage: $0 <opt1> <opt2> <opt3> <opt4>"
}
if [ $# -lt 3 ]; then
usage
exit;
fi
prog -a $1 -b $2 -c $3 -d $4 2>&1 | tee -a ~/$1.log
I want argument 4 to be optional, so if there's no argument for opt4, that it doesn't execute the -d argument in the actual program called 'prog'
Try:
#!/bin/ksh
usage ()
{
echo " Usage: $0 <opt1> <opt2> <opt3> <opt4>"
}
if [ $# -lt 3 ]; then
usage
exit;
fi
if [ -z $4 ]; then
prog -a $1 -b $2 -c $3 2>&1 | tee -a ~/$1.log
else
prog -a $1 -b $2 -c $3 -d $4 2>&1 | tee -a ~/$1.log
fi
1 Like
Or the shorter:
#!/bin/ksh
usage ()
{
echo " Usage: $0 <opt1> <opt2> <opt3> [<opt4>]"
}
[[ $# -lt 3 ]] && { usage; exit; }
prog -a $1 -b $2 -c $3 ${4:+-d $4} 2>&1 | tee -a ~/$1.log
1 Like
@bartus11
Would it be safer to put double quotes around the $4?:
...
if [ -z "$4" ]; then
...
@jlliagre
What exactly does "${4:+-d $4}" mean? Can this be applied to the other arguments as well, to make them optional?
Thanks
From ksh manual page (but this applies to all posix shells):
${parameter:+word}
If parameter is set and is non-null, substitute word. Otherwise
substitute nothing.
Here, "word" is "-d $4"
Yes.
This would require at least 3 arguments though, correct? Because if you only provided 2, the script wouldn't know which 2 arguments they are for and most likely use the first two options. Right? Or can this be circumvented somehow?
kshji
January 1, 2012, 4:17am
7
Here is generic solution. Argument order is not fixed and so on.
usage ()
{
echo " Usage: $0 -a value -b value -c value [ -d value ]" >&2
exit 1
}
#####################
a=""
b=""
c=""
d=""
# parse options
while [ $# -gt 0 ]
do
case "$1" in
-a) a="$2" ; shift ;;
-b) b="$2" ; shift ;;
-c) c="$2" ; shift ;;
-d) d="$2" ; shift ;;
--) shift; break ;;
-*) usage ;;
*) break ;; # arguments ...
esac
shift
done
# now $* include arguments
[ "$a" = "" ] && usage
[ "$b" = "" ] && usage
[ "$c" = "" ] && usage
if [ "$d" = "" ] ; then
prog -a "$a" -b "$b" -c "$c" 2>&1 | tee -a ~/"$a".log
else
prog -a "$a" -b "$b" -c "$c" -d "$d" 2>&1 | tee -a ~/"$a".log
fi
I used to check the $# first and proceed accordingly.
No, all arguments can be optional.
The arguments are positional so the shell definitely knows which ones they are.
Yes, you can just pass empty arguments. The corresponding options would then be ignored.