我想编写一个用作命令的 bash 脚本,它应该接受选项以及不带任何选项的参数。我能够使用 getops 编写接受选项的脚本,但无法为脚本提供不带选项的参数。
下面的例子运行良好
myscript -f filename
但是如果我不提供任何选项,相同的脚本也应该可以工作。
myscript username
答案1
#!/bin/bash
fname="/default"
while getopts f: arg ; do case $arg in
f) fname="$OPTARG";;
:) echo"${0##*/}: Must supply an argument to $OPTARG."
exit 1
;;
\?) echo "Invalid option. Abort"
exit 1
;;
esac
done
shift $(($OPTIND - 1))
# Demonstration
echo "fname=$fname"
echo "There are $# remaining arguments: $*"
例子:
$ myscript -f newfile
fname=newfile
There are 0 remaining arguments:
$ myscript arg1 arg2
fname=/default
There are 2 remaining arguments: arg1 arg2
$ myscript -f newfile arg1 arg2
fname=newfile
There are 2 remaining arguments: arg1 arg2
答案2
我知道您特别提到getopts
,但另一种选择是通过循环来循环遍历while
参数"$*"
:
file=""
user=""
other_args=""
while [ "$*" != "" ]; do
case $1 in
"-f")
file="$2"
shift
;;
"-u")
user="$2"
shift
;;
"--help"|"help"|"-?")
echo "usage: script.sh -f [file] -u [user] [other_args]"
break
;;
*) other_args="${other_args} $1" ;;
esac
shift
done
echo "file=${file}, user=${user}, other_args=${other_args}"
以下是脚本中其用法(以及其他一些内容)的一个例子a_pirate_says.sh
:
#!/bin/sh
me_file="tortuga"
me_crew="scallywags"
me_other_args=""
usage()
{
echo "usage: a_pirate_says.sh [arg] [arg] [arg]"
echo " arg An ARRRggument"
echo " arg Another AARrrrrgument"
echo " arg Pirates love AARRrrrrgumengs"
}
check_me_args()
{
if [ "$#" -eq 0 ]; then return 3; fi
me_return=0
while [ "$*" != "" ]; do
case $1 in
"-f") # we be specifically wanting me_file changed
me_file="$2"
shift
;;
"-c") # we be specifically wanting me_crew changed
me_crew="$2"
shift
;;
"yo")
if [ "$2" == "ho" ]; then
shift
if [ "$3" == "ho" ]; then
shift
echo "and a bottle of rum!"
else
echo "yo ho, a pirates life for me"
fi
else
echo "gabba gabba .. wait..."
fi
;;
"dead man tell no tales") echo "and live men tell no truth" ;;
"valar morghulis") echo "valar dohaeris" ;;
"help") me_return=1 ;;
"--help"|"-?") # ye specify multiple AArrrrgg's with the handy pipe
echo "Ye must really be needin help .."
usage
me_return=2
break
;;
*) me_other_args="${me_other_args} $1" ;;
esac
shift
done
return $me_return
}
# we be passin' the quoted "$@" so we be enabling the
# check_me_args function to handle passed in quotes
check_me_args "$@"
ye_return=$? # what say ye check_me_args????
if [ ! $ye_return -eq 0 ]; then
echo "To bad ${me_crew}! Weigh anchor we head out in a fortnight for ${me_file} .."
if [ "${me_other_args}" != "" ]; then
echo "If ye be disagreeing with my command, then to ye I say ${me_other_args}!!!!!"
fi
case $ye_return in
2) ;; # a true cry for help matty, we shall ignore this return value, aye!
1) echo "A true pirate ne'er asks for help .. they DEMANDS it!" ;;
3) echo "Ye did not put words upon the command line, I'm acquiesced to disincline your request" ;;
*) echo "BELAY THAT!" ;;
esac
exit 1
fi
echo "Welcome ${me_crew}! We be hoisting our sails to ${me_file} .."
if [ "${me_other_args}" != "" ]; then
echo "If ye be disagreeing with my command, then to ye I say ${me_other_args}!!!!!"
fi
如果您愿意的话,这只是处理 shell 参数的另一种方法。
希望有所帮助。