Arrays 为bash数组中的每个项运行管道
假设我有一个数组:Arrays 为bash数组中的每个项运行管道,arrays,bash,loops,pipe,Arrays,Bash,Loops,Pipe,假设我有一个数组: ITEMS=( "foo" "bar" "baz" ) 我要运行以下命令: cat template \ | my_command $ITEMS[1] \ | my_command $ITEMS[2] \ | my_command $ITEMS[3] \ > output 我不想为每个数组项硬编码my_命令,因为数组是动态的 我可以做到以下几点: cat template > output for var in "${ITEMS[@
ITEMS=(
"foo"
"bar"
"baz"
)
我要运行以下命令:
cat template \
| my_command $ITEMS[1] \
| my_command $ITEMS[2] \
| my_command $ITEMS[3] \
> output
我不想为每个数组项硬编码my_命令
,因为数组是动态的
我可以做到以下几点:
cat template > output
for var in "${ITEMS[@]}"; do
cat output | my_template $var > output
done
但这看起来很笨拙,因为它多次写入文件
当调用次数未知时,有没有办法将所有的
my_命令调用放入同一个命令中?下面是一种使用printf
和备受诟病的eval
的方法:
eval $(printf 'cat template '; printf '| my_command "%s" ' "${ITEMS[@]}") > output
仅当您确定项数组中没有恶意条目时才使用它。您可以将整个循环块重定向到输出,以便:
for var in "${ITEMS[@]}"; do
my_template "${var}" <template
done >output
这将要求:
my_template "foo" "bar" "baz" <template
my_模板“foo”“bar”“baz”使用一些好的老式递归
- 如果只有一个参数(
1)
case),则直接运行命令
- 如果有多个(
*)
案例),则使用第一个参数(${args[0]}
)运行它,并将其传递到多管道的递归调用,同时删除第一个参数(${args[@]:1}
)
multipipe(){
本地cmd=$1
本地args=(“${@:2}”)
案例${#args[@]}in
0) ;;
1) “$cmd”“${args[0]}”;;
*)“$cmd”“${args[0]}”|多管道“$cmd”“${args[@]:1}”;;
以撒
}
多管道my_命令“${ITEMS[@]}”输出
my_命令是否只接受一个输入参数?或者您可以重写my_command
以接受多个值吗?my_command
是一个我没有编写的外部程序,所以假设它必须采用提供的格式。我喜欢第一种方法,我想它在我的情况下会起作用,但如果(假设)它会起作用吗my_命令的每次调用都依赖于以前的输出?不,每次调用都独立于其他调用处理template
。@FelaMaslen您可能可以使用命名管道在循环中链接输入和输出:mypipe=$(mktemp-u);mkfifo-m600“${mypipe}”;对于“${ITEMS[@]}”中的var;执行我的_模板“${var}”>“${mypipe}”;完成;cat“${mypipe}”>输出;rm“${mypipe}”
这是最清晰的解决方案,不依赖于eval
+1.
my_template "foo" "bar" "baz" <template