我想使用for循环解析传递给Shell脚本的参数。假设现在有3个参数,类似于
for i in $1 $2 $3
应该可以胜任,但我无法预测参数数量,因此我希望使用一个正则表达式来获取范围,并使用$#作为最后一个参数的编号。我不知道如何在for循环中使用这些正则表达式,我尝试了以下代码:
for i in $[1-$#]
它并不能起到作用。循环只运行1次,而且1-$#被计算,而不是作为正则表达式使用。
如果您没有指定 in
子句,for
循环默认会循环遍历命令行参数:
for arg; do
echo "$arg"
done
如果您想明确地获取所有参数,则可以使用"$@"
。上述循环等同于:
for arg in "$@"; do
echo "$arg"
done
从bash手册中得知:
特殊参数
$@
— 扩展为位置参数,从一开始。当扩展发生在双引号内时,每个参数都会扩展为一个单独的单词。也就是说,"$@"
等价于"$1" "$2" ...
。如果双引号扩展发生在一个单词内部,则第一个参数的扩展将与原始单词的起始部分连接,最后一个参数的扩展将与原始单词的最后部分连接。当没有位置参数时,"$@"
和$@
扩展为空(即它们被删除)。
对于重度参数处理,getopt
+ shift
是正确的方式。 getopt
将预处理命令行,使用户可以以灵活的方式指定参数。例如,它将 -xzf
扩展为 -x -z -f
。它在所有标志之后添加一个 --
参数,用于将标志与文件名分开;这使您可以运行 cat -- -my-file
来显示 -my-file
的内容,而不会因前导破折号而出错。
尝试使用以下样板代码:
#!/bin/bash
eval set -- "$(getopt -o a:bch -l alpha:,bravo,charlie,help -n "$0" -- "$@")"
while [[ $1 != -- ]]; do
case "$1" in
-a|--alpha)
echo "--alpha $2"
shift 2
;;
-b|--bravo)
echo "--bravo"
shift
;;
-c|--charlie)
echo "--charlie"
shift
;;
-h|--help)
echo "Usage: $0 [-a ARG] [-b] [-c]" >&2
exit 1
;;
esac
done
shift
-a
和--alpha
。 -a
标志需要一个参数,因此在getopt
调用中指定为a:
和alpha:
,并在其case末尾具有shift 2
。for ((i=1; i<=$#; i++))
do
echo "${@:i:1}"
done
但是,John Kugelman展示的for arg
语法明显更可取。然而,在某些情况下,数组切片也很有用。此外,在这个版本中,就像John的版本一样,参数数组保持不变。使用shift
会丢弃其元素。
你应该注意,你试图使用方括号做的并不是正则表达式。
我建议做其他事情代替:
while [ -n "$1" ] ; do
# Do something with $1
shift
# Now whatever was in $2 is now in $1
done
shift
关键字将 $2 的内容移动到 $1,$3 移动到 $2,以此类推。
假设参数如下:
a b c d
shift
之后,参数现在为:
b c d
使用while循环,您可以解析任意数量的参数,甚至可以执行以下操作:
while [ -n "$1" ] ; do
if [ "$1" = "-f" ] ; then
shift
if [ -n "$1" ] ; then
myfile="$1"
else
echo "-f needs an additional argument"
end
fi
shift
done
for
循环的困难方式,而且不需要使用 shift 等操作。 - Jonathan Lefflerfor arg in "$@"
更容易,但如果你正在进行“严格”的参数解析,它就不够灵活了...你必须将中间值存储在临时变量中,这使得整个工作比使用 while 循环更加困难。 - DarkDustwhile (( $# > 0 ))
或while [ $# -gt 0 ]
。 - Dennis Williamson
getopts
更可取,而不是外部的getopt
,因为后者“无法处理空参数字符串或带有嵌入式空格的参数”。 - Dennis Williamsonman getopt
以查看您是否拥有新的增强版本,可以填补这些漏洞:“传统的getopt(1)实现无法处理参数和非选项参数中的空格和其他(特定于shell的)特殊字符。为了解决这个问题,此实现可以生成带引号的输出,必须再次由shell解释...” - John Kugelmangetopt
是否已增强。如果是,则返回退出状态4;较旧的getopt
将以0退出。 - John Kugelmangetopt
,那就完全没问题!”来限定这个建议,那就太好了! - John Kugelman