BCS*_*BCS 40 bash flags command-line
在脚本中间,我想检查命令行上是否传递了给定的标志.以下是我想要的,但看起来很难看:
if echo $* | grep -e "--flag" -q
then
echo ">>>> Running with flag"
else
echo ">>>> Running without flag"
fi
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
注:我明确地不希望列出一个开关/ getopt的所有标志.(在这种情况下,任何这样的东西都会变成完整脚本的一半或更多.而且if的主体也只是设置了一组变量)
Pau*_*ce. 60
替代你正在做的事情:
if [[ $* == *--flag* ]]
Run Code Online (Sandbox Code Playgroud)
另见BashFAQ/035.
注意:这也将匹配,
--flags-off因为它是一个简单的子字符串检查.
Eli*_*lka 11
您可以采用简单的方法,并迭代参数以测试每个参数与给定参数(例如-t)的相等性。
把它放到一个函数中:
has_param() {
local term="$1"
shift
for arg; do
if [[ $arg == "$term" ]]; then
return 0
fi
done
return 1
}
Run Code Online (Sandbox Code Playgroud)
...并将其用作测试表达式中的谓词:
if has_param '-t' "$@"; then
echo "yay!"
fi
if ! has_param '-t' "$1" "$2" "$wat"; then
echo "nay..."
fi
Run Code Online (Sandbox Code Playgroud)
如果你想拒绝空参数,在循环体的顶部添加一个退出点:
for arg; do
if [[ -z "$arg" ]]; then
return 2
fi
# ...
Run Code Online (Sandbox Code Playgroud)
这是非常易读的,不会给你误报,比如模式匹配或正则表达式匹配。
它还允许在任意位置放置标志,例如,您可以放置-h在命令行的末尾(不考虑它的好坏)。
但是,我想得越多,就越困扰我。
使用函数,您可以采用任何实现(例如getopts),并重用它。封装规则!
但即使有命令,这种力量也会成为缺陷。如果你一次又一次地使用它,你每次都会解析所有的参数。
我倾向于重用,但我必须意识到其中的含义。相反的方法是在脚本顶部解析这些参数一次,正如您所担心的那样,并避免重复解析。
您仍然可以封装那个 switch case,它可以像您决定的那样大(您不必列出所有选项)。
我通常会在案例陈述中看到这一点.以下是git-repack脚本的摘录:
while test $# != 0
do
case "$1" in
-n) no_update_info=t ;;
-a) all_into_one=t ;;
-A) all_into_one=t
unpack_unreachable=--unpack-unreachable ;;
-d) remove_redundant=t ;;
-q) GIT_QUIET=t ;;
-f) no_reuse=--no-reuse-object ;;
-l) local=--local ;;
--max-pack-size|--window|--window-memory|--depth)
extra="$extra $1=$2"; shift ;;
--) shift; break;;
*) usage ;;
esac
shift
done
Run Code Online (Sandbox Code Playgroud)
请注意,这允许您检查短标志和长标志.extra在这种情况下,使用变量构建其他选项.
您可以在bash中使用getopt关键字.
来自http://aplawrence.com/Unix/getopts.html:
getopt的
这是一个独立的可执行文件,已经存在很长时间了.较旧的版本缺乏处理引用参数的能力(foo"这将无效"c)和版本可以,笨拙地这样做.如果您运行的是最近的Linux版本,那么"getopt"可以做到这一点; SCO OSR5,Mac OS X 10.2.6和FreeBSD 4.4的旧版本没有.
这个迷你脚本中显示了"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
Run Code Online (Sandbox Code Playgroud)