我试图编写一个程序来处理作为程序输入的文件,但我想支持值的管道输入以及通过参数发送它们。
例如,有人可能希望使用标志-dvs在当前目录中的所有文件上运行程序:
find . -type f | program -dvs
或者您可能想要这样做,但对于$ FILES_TO_CHECK变量中的所有文件:
echo "$FILES_TO_CHECK" | program -dvs
这是我到目前为止的代码:
tmp1() {
local in=("$@")
if read -t 0 -u 0; then
local pipe=""
read -d '' -u 0 pipe
in+=(${pipe})
fi
local param
for param in "${!in[@]}"; do
echo "'$param' => '${in[$param]}'"
done
}
测试:
echo "cba" "bca" "cba abc" | tmp1 "a" "b" "c" "abc" "abc cba"
echo; echo; echo
find . -type f
find . -type f | tmp1 "a" "b" "c" "abc" "abc cba"
以上给出了以下输出:
'0' => 'a'
'1' => 'b'
'2' => 'c'
'3' => 'abc'
'4' => 'abc cba'
'5' => 'cba'
'6' => 'bca'
'7' => 'cba'
'8' => 'abc'
./1
./2
./3
'0' => 'a'
'1' => 'b'
'2' => 'c'
'3' => 'abc'
'4' => 'abc cba'
哪个很接近,但不完全是我想要的:
'0' => 'a'
'1' => 'b'
'2' => 'c'
'3' => 'abc'
'4' => 'abc cba'
'5' => 'cba'
'6' => 'bca'
'7' => 'cba abc'
./1
./2
./3
'0' => 'a'
'1' => 'b'
'2' => 'c'
'3' => 'abc'
'4' => 'abc cba'
'5' => './1'
'6' => './2'
'7' => './3'
我不确定顶级情况(保持空间字符来自管道值)是可能的,但如果是,你会怎么做呢?
至于第二种情况,为什么find的输出不会被程序读取?
编辑:如果还有其他更好的方法,我也会听到所有的耳朵。 之后的实际循环要复杂得多,所以我想避免为参数设置一个循环,而为管道值设置另一个循环。
答案 0 :(得分:1)
您的append = TRUE
正在从标准输入读取空分隔的记录,但您的测试是发送空格分隔的字符串。用
tmp
(这假定printf '%s\0' "cba" "bca" "cba abc" | tmp1 "a" "b" "c" "abc" "abc cba"
find . -type f -print0 | tmp1 ...
的版本可以输出以null结尾的文件名。)
在find
内,您需要循环输入以获取每个文件,然后在将其添加到数组时引用tmp
$pipe
如果您使用的是if read -t 0 -u 0; then
local pipe=""
while read -d '' pipe; do
in+=("$pipe")
done
fi
4.4或更高版本,则可以使用bash
代替循环。
readarray