如何在将$@
存储到另一个函数中的另一个变量后进行迭代?
注意这是关于sh shell的,而不是bash。
我的代码(超级简化):
#! /bin/sh
set -- a b "c d"
args=
argv() {
shift # pretend handling options
args="$@" # remaining arguments
}
fun() {
for arg in "$args"; do
echo "+$arg+"
done
}
argv "$@"
fun
输出:
+b c d+
我想:
+b+
+c d+
特殊变量$@
存储保留空格的argv。 for循环可以遍历$@
,也可以保留空格。
set -- a b "c d"
for arg in "$@"; do
echo "+$arg+"
done
输出:
+a+
+b+
+c d+
但是,一旦将$@
分配给另一个变量,保留的空白就会消失。
set -- a b "c d"
args="$@"
for arg in "$args"; do
echo "+$arg+"
done
输出
+a b c d+
没有引号:
for arg in $args; do
echo "+$arg+"
done
输出:
+a+
+b+
+c+
+d+
在bash中,可以使用数组来完成。
set -- a b "c d"
args=("$@")
for arg in "${args[@]}"; do
echo "+$arg+"
done
输出:
+a+
+b+
+c d+
可以在sh shell中完成吗?
答案 0 :(得分:1)
如果您知道shift
已执行fun
,则可以在shift
内再次使用argv
。
#! /bin/sh
set -- a b "c d"
args=
argv() {
shifted=1 # pretend handling options
shift $shifted
}
fun() {
[ -n $shifted ] && shift $shifted
for arg; do
echo "+$arg+"
done
}
argv "$@"
fun "$@"
输出:
+b+
+c d+
答案 1 :(得分:0)
以下是两个解决方法。两者都有警告。
首先解决方法:在参数之间添加换行符,然后使用read
。
set -- a b " c d "
args=
argv() {
shift
for arg in "$@"; do
args="$args$arg\n"
done
}
fun() {
printf "$args" | while IFS= read -r arg; do
echo "+$arg+"
done
}
argv "$@"
fun
输出:
+b+
+ c d +
请注意,即使之前和之后的空格也会被保留。
警告:如果参数包含换行符,则会被搞砸。
第二种解决方法:在参数周围加上引号,然后使用eval
。
set -- a b " c d "
args=
argv() {
shift
for arg in "$@"; do
args="$args \"$arg\""
done
}
fun() {
for arg in "$@"; do
echo "+$arg+"
done
}
argv "$@"
eval fun "$args"
警告:如果参数包含引号,那么你就搞砸了。