比如,我有一个脚本,用这行代码调用:
./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
或者这个:
./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile
什么是公认的解析方式,以便在每种情况下(或两者的某种组合)$v、$f和$d都将设置为true,而$outFile将等于/fiz/someOtherFile?
比如,我有一个脚本,用这行代码调用:
./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
或者这个:
./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile
什么是公认的解析方式,以便在每种情况下(或两者的某种组合)$v、$f和$d都将设置为true,而$outFile将等于/fiz/someOtherFile?
当前回答
我最终实现了公认答案的dash(或/bin/sh)版本,基本上不使用数组:
while [[ $# -gt 0 ]]; do
case "$1" in
-v|--verbose) verbose=1; shift;;
-o|--output) if [[ $# -gt 1 && "$2" != -* ]]; then
file=$2; shift 2
else
echo "-o requires file-path" 1>&2; exit 1
fi ;;
--)
while [[ $# -gt 0 ]]; do BACKUP="$BACKUP;$1"; shift; done
break;;
*)
BACKUP="$BACKUP;$1"
shift
;;
esac
done
# Restore unused arguments.
while [ -n "$BACKUP" ] ; do
[ ! -z "${BACKUP%%;*}" ] && set -- "$@" "${BACKUP%%;*}"
[ "$BACKUP" = "${BACKUP/;/}" ] && break
BACKUP="${BACKUP#*;}"
done
其他回答
如果您正在制作可与其他实用程序互换的脚本,下面的灵活性可能很有用。
以下任一项:
command -x=myfilename.ext --another_switch
Or:
command -x myfilename.ext --another_switch
代码如下:
STD_IN=0
prefix=""
key=""
value=""
for keyValue in "$@"
do
case "${prefix}${keyValue}" in
-i=*|--input_filename=*) key="-i"; value="${keyValue#*=}";;
-ss=*|--seek_from=*) key="-ss"; value="${keyValue#*=}";;
-t=*|--play_seconds=*) key="-t"; value="${keyValue#*=}";;
-|--stdin) key="-"; value=1;;
*) value=$keyValue;;
esac
case $key in
-i) MOVIE=$(resolveMovie "${value}"); prefix=""; key="";;
-ss) SEEK_FROM="${value}"; prefix=""; key="";;
-t) PLAY_SECONDS="${value}"; prefix=""; key="";;
-) STD_IN=${value}; prefix=""; key="";;
*) prefix="${keyValue}=";;
esac
done
来自digitalpeer.com,稍作修改:
用法myscript.sh-p=my_prefix-s=dirname-l=libname
#!/bin/bash
for i in "$@"
do
case $i in
-p=*|--prefix=*)
PREFIX="${i#*=}"
;;
-s=*|--searchpath=*)
SEARCHPATH="${i#*=}"
;;
-l=*|--lib=*)
DIR="${i#*=}"
;;
--default)
DEFAULT=YES
;;
*)
# unknown option
;;
esac
done
echo PREFIX = ${PREFIX}
echo SEARCH PATH = ${SEARCHPATH}
echo DIRS = ${DIR}
echo DEFAULT = ${DEFAULT}
要更好地理解${i#*=},请在本指南中搜索“Substring Removal”。它在功能上等同于调用一个不需要的子流程的‘sed’s/[^=]*=//'<<<“$i”`或调用两个不需要子流程的“echo”$i”|sed’s/[^=]*=//'`。
getopt()/getopts()是一个很好的选项。从此处复制:
“getopt”的简单用法如下小脚本所示:
#!/bin/bash
echo "Before getopt"
for i
do
echo $i
done
args=`getopt abc:d $*`
set -- $args
echo "After getopt"
for i
do
echo "-->$i"
done
我们所说的是,-b、 -c或-d将被允许,但-c后面跟着一个参数(“c:”表示)。如果我们称之为“g”并尝试:
bash-2.05a$ ./g -abc foo
Before getopt
-abc
foo
After getopt
-->-a
-->-b
-->-c
-->foo
-->--
我们从两个参数开始“getopt”将选项和每个人都有自己的论点。它也是添加了“--”。
我认为这个很简单:
#!/bin/bash
#
readopt='getopts $opts opt;rc=$?;[ "$rc$opt" = "0?" ]&&exit 1;[ $rc = 0 ]||{ shift $[OPTIND-1];false; }'
opts=vfdo:
# Enumerating options
while eval "$readopt"
do
echo OPT:$opt ${OPTARG+OPTARG:$OPTARG}
done
# Enumerating arguments
for arg
do
echo ARG:$arg
done
调用示例:
./myscript -v -do /fizz/someOtherFile -f ./foo/bar/someFile
OPT:v
OPT:d
OPT:o OPTARG:/fizz/someOtherFile
OPT:f
ARG:./foo/bar/someFile
使用bash模块中的模块“参数”
例子:
#!/bin/bash
. import.sh log arguments
NAME="world"
parse_arguments "-n|--name)NAME;S" -- "$@" || {
error "Cannot parse command line."
exit 1
}
info "Hello, $NAME!"