假设我有一个 bash 函数,它应该删除所有以“-”开头的参数,直到它得到一个不以“-”开头的参数。
gmx(){
local options=( );
while [ "${1:0:1}" == "-" ]; do
options+=("${1}")
shift 1;
done
echo "first legit arg: $1"
"$@" # omg will be executed here, like `omg --rolo`
}
gmx -a -f -c omg --rolo
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但我想知道这是否是一个很好的通用解决方案,可以始终让 'omg' 成为第一个“合法”参数。是否有任何可能失败的边缘情况?
换句话说,-a、-f、-c 都是 gmx 的参数。而omg接下来的一切都将在子进程中运行。
官方和最好的方法是 t 使用getopts内置来解析命令行选项。
有关更多信息,请参阅手册页。
注意可能很重要:bash不支持长选项。
如果你喜欢用脚本处理长选项,你有两个支持它们的 shell:ksh93和bosh. 两种 shell 都支持长选项,就像getopt(3)Solaris 上的 libc 中的函数所支持的那样。请参阅 bosh 手册页(当前从第 43 页开始:
http://schlytools.sourceforge.net/man/man1/bosh.1.html
getopts "f:(file)(input-file)o:(output-file)" OPT
Run Code Online (Sandbox Code Playgroud)
支持例如-f带有参数的选项,并且该选项有一个长选项别名--file和此选项的第二个别名--input-file
ksh93 也支持这一点,即使它没有记录在 ksh93 手册页中。
while getopts ':' opt; do
: # This is where ordinarily a case statement would be,
# case $opt in ... esac
# But we use : as a no-op
done
shift "$(( OPTIND - 1 ))"
printf 'arg: %s\n' "$@"
Run Code Online (Sandbox Code Playgroud)
这用于getopts解析命令行选项。while一旦找到第一个非选项,循环就会终止,并且shift将把处理过的选项移出$@只留下非选项操作数$@。
剧本
#!/bin/sh
gmx () {
while getopts ':' opt; do
:
done
shift "$(( OPTIND - 1 ))"
printf 'arg: %s\n' "$@"
}
gmx -a --foo -c omg lol
Run Code Online (Sandbox Code Playgroud)
会输出
arg: omg
arg: lol
Run Code Online (Sandbox Code Playgroud)
由于您对实际选项不感兴趣,因此您显然可以执行一个简单的循环,例如
for opt do
case $opt in
-*) shift ;;
*) break
esac
done
printf 'arg: %s\n' "$@"
Run Code Online (Sandbox Code Playgroud)
这会遍历所有参数,将每个以破折号开头的参数移开,并以第一个不以破折号开头的参数结束。
| 归档时间: |
|
| 查看次数: |
1261 次 |
| 最近记录: |