plist
我有一个能够调用head
和命令的函数tail
。但对于处理区域,我调用了不同的函数pregion
。
# --- plist ---
("-H"|"--head")
local -r hn="$2" ; shift 2 ;;
("-T"|"--tail")
local -r tm="$2" ; shift 2 ;;
("--FS") # field separator
local fs="$2" ; shift 2 ;;
("--incl")
local incl+=("$2") ; shift 2 ;; # file type suffix
("--excl")
local excl+=("$2") ; shift 2 ;; # file type suffix
("--RP")
local pn=$2 ; shift 2 ;;
("--RQ")
local qn=$2 ; shift 2 ;;
("--dyn"|"--dynamic")
local dyn="1" ; shift 1 ;;
("-C"|"--context")
local ctx=$2 ; shift 2 ;;
("-d"|"--directory")
local fdir=$2 ; shift 2 ;;
(--)
shift; break ;;
...
if [[ -v hn ]]; then
head -v -hn "$n"
elif [[ -v tm ]]; then
tail -v -n "$tm"
elif [[ -v dyn ]]; then
pregion "$@" # requires original options here
fi
对于head
and tail
,我只使用选项-H
' -T
, --FS
, and --incl
。因为我在处理选项时使用shift
,所以我需要原始plist
输入参数的副本,因为我不能简单地传递"$@"
给pregion
.
这将调用head
或tail
plist -H 8 ./01cuneus
plist -T 13 ./01cuneus
调用示例pregion
plist --dyn -C 8 "Martin" ./01cuneus
plist --incl .texi --incl .org --RP 8 --RQ 13 ./01cuneus
plist --incl .texi --incl .org --dyn -C 8 "Martin" ./01cuneus
答案1
将原始参数复制到数组中,并将其与pregion
.例如
plist() {
local -a origargs=("$@")
...
case
...
esac
...
if
...
elif [[ -v dyn ]]; then
pregion "${origargs[@]}"
fi
答案2
您确实可以将 的内容保存$@
到数组中
plist() {
local args
args=("$@")
case $1 in ...
# some shifting etc.
esac
if something; then
pregion "${args[@]}"
fi
}
但是,这意味着pregion
需要再次进行整个选项处理。实际上,您可以在两个地方实现相同的过程。那么返回无效选项的错误又如何呢plist
?在确定是否要致电之前,您不能这样做pregion
,因为它可能接受某些选项,但plist
不接受。
相反,我建议仅执行一次选项解析,然后使用pregion
已解析为各个参数的适当值进行调用:
plist() {
local args
args=("$@")
local this=default that=otherdefault
local call_pregion=
case $1 in ...
this) this=$2; shift; shift;;
that) that=$2; shift; shift;;
dyn) call_pregion=1
esac
if [ "$call_pregion" ]; then
pregion "$this" "$that"
fi
}
这样pregion
就可以从列表中的静态位置获取值,例如$1
for$this
和$2
for $that
。
另外,顺便说一句,使用shift 2
那里是有风险的。根据 shell 的不同,它可能会默默地失败,因为没有足够的参数来转换。例如,set a b c; shift 4; echo $1
在 Dash 中会出现错误并退出,但在 Bash 中,它会很高兴地只打印a
。如果用户给出的选项没有相应的选项参数,这可能会使您的选项解析陷入循环。