在脚本中间,我想检查命令行上是否传递了给定的标志。以下是我想要的,但看起来很难看:
if echo $* | grep -e "--flag" -q
then
echo ">>>> Running with flag"
else
echo ">>>> Running without flag"
fi
有更好的方法吗?
注意:我明确地不想要列出switch / getopt中的所有标志。 (在这种情况下,任何这样的东西都会变成完整脚本的一半或更多。而且if的主体也只是设置了一组变量)
答案 0 :(得分:53)
答案 1 :(得分:9)
我通常会在案例陈述中看到这一点。以下是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
请注意,这允许您检查短标志和长标志。在这种情况下,使用extra
变量构建其他选项。
答案 2 :(得分:6)
您可以在bash中使用getopt关键字。
来自http://aplawrence.com/Unix/getopts.html:
getopt的
这是一个独立的可执行文件,已经存在很长时间了。 较旧的版本缺乏处理引用参数的能力(foo a“this 将不会工作“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
答案 3 :(得分:1)
我对Eliran Malka的答案做了一些小改动:
此函数可以评估不同的参数同义词,例如“ -q”和“ --quick”。此外,当找到参数时,它不使用return 0/1,而是使用echo来返回非null值:
function has_param() {
local terms="$1"
shift
for term in $terms; do
for arg; do
if [[ $arg == "$term" ]]; then
echo "yes"
fi
done
done
}
# Same usage:
# Assign result to a variable.
FLAG_QUICK=$(has_param "-q --quick" "$@") # "yes" or ""
# Test in a condition using the nonzero-length-test to detect "yes" response.
if [[ -n $(has_param "-h --help" "$@") ]]; then;
echo "Need help?"
fi
# Check, is a flag is NOT set by using the zero-length test.
if [[ -z $(has_param "-f --flag" "$@") ]]; then
echo "FLAG NOT SET"
fi
答案 4 :(得分:0)
您可以采用简单的方法,并遍历参数以测试每个参数与给定参数(例如-t
)是否相等。
将其放入函数中
has_param() {
local term="$1"
shift
for arg; do
if [[ $arg == "$term" ]]; then
return 0
fi
done
return 1
}
…并将其用作测试表达式中的谓词:
if has_param '-t' "$@"; then
echo "yay!"
fi
if ! has_param '-t' "$1" "$2" "$wat"; then
echo "nay..."
fi
如果要拒绝空参数,请在循环主体顶部添加一个退出点:
for arg; do
if [[ -z "$arg" ]]; then
return 2
fi
# ...
这是可读性,并且不会像模式匹配或正则表达式匹配那样给您带来误报。
它还将允许将标志放置在任意位置,例如,您可以在命令行的末尾放置-h
(而不考虑它的好坏)。
但是,我对它的思考越深,越让我感到困扰。
使用一个函数,您可以采用任何实现(例如getopts
),然后重复使用。封装rulez!
但是即使使用命令,这种力量也会成为缺陷。如果要一次又一次地使用它,则每次都将解析所有参数。
答案 5 :(得分:0)
不是替代方案,而是一种改进。
if echo $* | grep -e "\b--flag\b" -q
寻找word boundaries将确保确实获得选项--flag
,而--flagstaff
和--not-really--flag
都不是
答案 6 :(得分:0)
对 Dennis Williamson 的 answer 进行修改,并提供了简短形式参数的附加示例。
if [[ \ $*\ == *\ --flag\ * ]] || [[ \ $*\ == *\ -f\ * ]]
它解决了误报匹配 --flags-off
甚至 --another--flag
的问题(更流行的这种情况是单虚线参数:--one-more-flag
for *-f*
)。>
\
(反斜杠 + 空格)表示 [[ ]]
中表达式的空格。在 $*
周围放置空格可以确保参数既不接触行的开头也不接触行的结尾,它们只接触空格。现在可以在带参数的行中搜索由空格包围的目标标志。
答案 7 :(得分:0)
[!0-9]*[!0-9]