如何为标志创建带有可选参数的 bash 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15524839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a bash script with optional parameters for a flag
提问by ederlf
I'm trying to create a script which will have a flag with optional options. With getopts it's possible to specify a mandatory argument (using a colon) after the flag, but I want to keep it optional.
我正在尝试创建一个脚本,该脚本将有一个带有可选选项的标志。使用 getopts 可以在标志后指定一个强制参数(使用冒号),但我想保持它是可选的。
It will be something like this:
它会是这样的:
./install.sh -a 3
or
或者
./install.sh -a3
where 'a' is the flag and '3' is the optional parameter that follows a.
其中'a'是标志,'3'是a后面的可选参数。
Thanks in advance.
提前致谢。
采纳答案by chepner
The getopt
external program allows options to have a single optional argument by adding a double-colon to the option name.
该getopt
外部程序可以选择加入了双冒号的选项名称有一个可选参数。
# Based on a longer example in getopt-parse.bash, included with
# getopt
TEMP=$(getopt -o a:: -- "$@")
eval set -- "$TEMP"
while true ; do
case "" in
-a)
case "" in
"") echo "Option a, no argument"; shift 2 ;;
*) echo "Option a, argument "; shift 2;;
esac ;;
--) shift; break ;;
*) echo "Internal error!"; exit 1 ;;
esac
done
回答by Dipto
The following is without getopt
and it takes an optional argument with the -a flag:
以下是没有的getopt
,它需要一个带有 -a 标志的可选参数:
for WORD; do
case $WORD in
-a?) echo "single arg Option"
SEP=${WORD:2:1}
echo $SEP
shift ;;
-a) echo "split arg Option"
if [[ ${2:0:1} != "-" && ${2:0:1} != ""]] ; then
SEP=
shift 2
echo "arg present"
echo $SEP
else
echo "optional arg omitted"
fi ;;
-a*) echo "arg Option"
SEP=${WORD:2}
echo $SEP
shift ;;
-*) echo "Unrecognized Short Option"
echo "Unrecognized argument"
;;
esac
done
Other options/flags also can be added easily.
也可以轻松添加其他选项/标志。
回答by Alepac
My solution:
我的解决方案:
#!/bin/bash
count=0
skip=0
flag="no flag"
list=($@) #put args in array
for arg in $@ ; do #iterate over array
count=$(($count+1)) #update counter
if [ $skip -eq 1 ]; then #check if we have to skip this args
skip=0
continue
fi
opt=${arg:0:2} #get only first 2 chars as option
if [ $opt == "-a" ]; then #check if option equals "-a"
if [ $opt == $arg ] ; then #check if this is only the option or has a flag
if [ ${list[$count]:0:1} != "-" ]; then #check if next arg is an option
skip=1 #skip next arg
flag=${list[$count]} #use next arg as flag
fi
else
flag=${arg:2} #use chars after "-a" as flag
fi
fi
done
echo $flag
回答by Randy Howard
Use the getopt feature. On most systems, man getopt
will yield documentation for it, and even examples of using it in a script. From the man page on my system:
使用 getopt 功能。在大多数系统上,man getopt
会生成它的文档,甚至是在脚本中使用它的示例。从我系统上的手册页:
The following code fragment shows how one might process the arguments for a command that can take the options -a and -b, and the option -o, which requires an argument.
以下代码片段显示了如何处理可以采用选项 -a 和 -b 以及需要参数的选项 -o 的命令的参数。
args=`getopt abo: $*`
# you should not use `getopt abo: "$@"` since that would parse
# the arguments differently from what the set command below does.
if [ $? != 0 ]
then
echo 'Usage: ...'
exit 2
fi
set -- $args
# You cannot use the set command with a backquoted getopt directly,
# since the exit code from getopt would be shadowed by those of set,
# which is zero by definition.
for i
do
case "$i"
in
-a|-b)
echo flag $i set; sflags="${i#-}$sflags";
shift;;
-o)
echo oarg is "'""'"; oarg=""; shift;
shift;;
--)
shift; break;;
esac
done
echo single-char flags: "'"$sflags"'"
echo oarg is "'"$oarg"'"
This code will accept any of the following as equivalent:
此代码将接受以下任何等效项:
cmd -aoarg file file
cmd -a -o arg file file
cmd -oarg -a file file
cmd -a -oarg -- file file
回答by Xavier S.
In bash there is some implicit variable:
在 bash 中有一些隐式变量:
$#: contains number of arguments for a called script/function
#!/bin/ksh
if [ $# -ne 2 ]
then
echo "Wrong number of argument - expected 2 : $#"
else
echo "Argument list:"
echo "\t##代码##"
echo "\t"
echo "\t"
fi
: contains names of script/function
: contains first argument
: contains second argument
...
$n: contains n-th argument
For example:
例如:
##代码##