下面的代码是基于mwe
我编写的脚本的 mwe,其中我以我认为通常的方式指定了标志。但我看到了非常奇怪的行为。如果我输入mwe -e
或者mwe -n
它认为没有参数并返回no arg
。如果我输入mwe -k
或mwe -i
它认为argType
不是"-"
并返回breaking
。如果我注释掉以 a 结尾的四行,#
代码将按预期工作。这表明问题是由while
循环引起的。有人可以解释一下发生了什么吗?
#!/bin/bash
foo=0
argType=`echo "$1" | cut -c 1`
while [ 1 -gt 0 ] ; #
do #
if [ $# -eq 0 ] ; then
echo no arg
exit
elif [ "$argType" != "-" ] ; then
#No more flags
echo breaking
break #
elif [ "$1" = "-n" ] ; then
foo=1
shift
elif [ "$1" = "-e" ] ; then
foo=2
shift
elif [ "$1" = "-i" ] ; then
foo=3
shift
elif [ "$1" = "-k" ] ; then
foo=4
shift
fi
done #
echo This is foo: $foo
答案1
第三行应该是
argType=$(printf "%s" "$1" | cut -c 1)
正如评论中提到的,echo
将参数(例如选项)解释为-e
选项,因此-e
不会传递给cut
.更糟糕的是,作为一个特例,选项结束标志--
不可用于echo
。那么,你需要printf
,无论如何,这通常更好。
既然你在bash
,你可以采纳@steeldriver的建议并使用argType=${1:0:1}
(这意味着:对于参数1,从字符0开始并获取1个字符)而不是管道。但请注意,这在 POSIX shell 中不可用。
也更喜欢$()
而不是反引号,因为后者会损害可读性,尤其是在嵌套时。
最后,请注意您正在转移,因此,即使在更正之后,如果您尝试./myscript -e -i
,最终[ $# -eq 0 ]
将为 true 并且执行将由 终止exit
。也许这是有意为之,也许不是,但最终echo
不会触发最后一个。
答案2
从你的问题来看,并不清楚你想要什么!
无论如何,您似乎想要与最后一个参数对应的数字
#!/bin/bash
foo=0;
while [[ $# -gt 0 ]]; do
case "${1}" in
'-n')
foo=1;
shift
;;
'-e')
foo=2;
shift
;;
'-i')
foo=3;
shift
;;
'-k')
foo=4;
shift
;;
*)
echo "Invalid flag";
exit 1;
;;
esac
done
echo "This is foo: $foo"
相反,如果您想要一种在处理之前处理和验证参数的机制,您可以使用类似
#!/bin/bash
inputf='';
outputf='';
text='';
format='';
while [[ $# -gt 0 ]];do
case "${1}" in
'-i')
inputf="${2}";
shift 2
;;
'-o')
outputf="${2}";
shift 2
;;
'-t')
text="${2}";
shift 2
;;
'-f')
format="${2}";
shift 2
;;
esac
done