在Bash中处理具有多个参数的命令行选项 [英] Processing command line options with multiple arguments in Bash
问题描述
我一直在研究使用bash脚本处理命令行参数。我有多个可选参数,每个参数都有一个或多个操作数。一个示例是:
I have been researching on using bash scripts to process command-line arguments. I have multiple optional arguments, each of which have one or more operands. An example is:
./script.sh -f file1 file2 -s server1 server2
-f
本身是可选的,但必须后面跟文件名; -s
是可选的,可以不使用任何操作数或操作数来使用。
-f
itself is optional, but must be followed by filename; -s
is optional, can be used without any operands or operands.
我知道我可以强制放置在操作数上,因此我只处理一个操作数的参数,并且可以使用 case $ 1 $ 2 shift
进行处理。
I know I can force putting "" on operands so I only deal with arguments with one operand and can use case $1 $2 shift
to process it.
但我对此感兴趣,但不使用引号,只是为用户节省了一些打字时间。
But I am interested in doing so without quotes, just to save some typing for the users.
一个粗略的主意将被读为 $ @
作为一个字符串,并用空格隔开,然后用-/-
定位参数,并在其后分配操作数。也许我可以使用数组来做到这一点?
A rough idea would be read in "$@"
as one string, and separate them by space, then locate arguments with -/--
and assign operands following them. Maybe I can use an array to do that?
任何建议都将受到欢迎。
Any suggestions would be welcome.
推荐答案
感谢您的精彩建议。花了更多时间后,我决定采用以下解决方案:
Thanks folks for your wonderful suggestions. After spending some more time I resolved to the solution below:
简单地说,我使用 case
并进行少量检查确定参数是否为选项。我在参数处理期间仅使用alter flag变量,然后使用flags确定我将执行的功能。以某种方式,我可以选择不同顺序的选项。
Simply put, I use case
and few checks to determine if the argument is an option or not. I use only alter flag variables during argument processing and then use the flags to determine what functions I will perform. In a way that I can have options in different order.
main(){
#标志,1为假,0为真。这是该死的bash LOCAL_DEPLOY = 1
SERVER_DEPLOY = 1 DRY_RUN = 0
main(){
# flags, 1 is false, 0 is true. it's the damn bash LOCAL_DEPLOY=1 SERVER_DEPLOY=1 DRY_RUN=0
FILES=("${ALLOWEDFILES[@]}");
DEPLOYTARGET=("${ALLOWEDSERVERS[@]}");
if [ $# -eq 0 ]
then
printf -- "Missing optins, perform DRY RUN\nFor help, run with -h/--help\n"
for target in "${FILES[@]}"; do generate "$target"; done
echo "....dry run: markdown files generated in rendered/"
exit 0
fi
while true ; do
case "$1" in
-f |--file) # required operands
case "$2" in
"") die $1 ;;
*)
FILES=($2)
for i in "${FILES[@]}"; do
if is_option $i; then die $1; fi # check for option
if ! check_allowed $i ${ALLOWEDFILES[@]}; then exit 1; fi
done;
shift 2;; # input FILES are good
esac ;;
-l|--local) # no operands expected
DRY_RUN=1 # turn off dryrun
LOCAL_DEPLOY=0 # turn on local deploy
shift ;;
-s|--server) # optional operands
case "$2" in
"") shift ;;
*)
DEPLOYTARGET=($2) # use input
for i in "${DEPLOYTARGET[@]}"; do
if is_option $i; then die $1; fi # check for option
if ! check_allowed $i ${ALLOWEDSERVERS[@]}; then exit 1; fi
done ; shift 2;; # use input value
esac
DRY_RUN=1
SERVER_DEPLOY=0
;;
-n|--dryrun) # dry-run:generate markdown files only
DRY_RUN=0
shift ;;
-h|--help) # docs
print_help
exit 0
;;
--) shift; break ;;
-?*)
printf 'ERROR: Unkown option: %s\nExisting\n\n' "$1" >&2
print_help
exit 1
shift
;;
*)
break ;;
esac
done
echo "choose files: ${FILES[@]}"
echo ""
# dry-run
if [ $DRY_RUN == 0 ]; then
echo "..perform dry run.."
for target in "${FILES[@]}"; do generate "$target"; done
echo "....dry run: markdown files generated in rendered/"
exit 0
fi
# local-deploy
if [ $LOCAL_DEPLOY == 0 ] && [ $SERVER_DEPLOY != 0 ]; then
echo "..deploy locally"
for target in "${FILES[@]}"; do
generate "$target" > /dev/null
deploylocal "$target"
done;
# sync hexo-gcs hexo-yby
cd "$(dirname $HEXOLOCATION)"
./syncRepo.sh
printf -- "....hexo-gcs hexo-yby synced\n"
cd $CURRENTLOCATION
fi
# server-deploy
if [ $SERVER_DEPLOY == 0 ]; then
echo "..deploy on servers: ${DEPLOYTARGET[@]}"
echo ""
for target in "${FILES[@]}"; do # deploy locally
generate "$target" > /dev/null
deploylocal "$target"
done
# sync hexo-gcs hexo-yby
cd "$(dirname $HEXOLOCATION)"
./syncRepo.sh
printf -- "....hexo-gcs hexo-yby synced\n"
cd $CURRENTLOCATION
# deploy to selected server: git or gcp
for dt in "${DEPLOYTARGET[@]}"; do
deployserver $dt
done
fi
}
这篇关于在Bash中处理具有多个参数的命令行选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!