我坚持了一种奇怪的readarray
指挥行为。
美国man bash
:
readarray
Read lines from the standard input into the indexed array variable array
但这些脚本不起作用(数组为空):
unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]}
unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]}
这些工作:
unset arr; readarray arr < /etc/passwd ; echo ${#arr[@]}
unset arr; mkfifo /tmp/fifo; (echo a; echo b; echo c) > /tmp/fifo & mapfile arr < /tmp/fifo ; echo ${#arr[@]}
水管出了什么问题?
答案1
要确保readarray
命令在当前 shell 中执行,请使用进程替换代替管道:
readarray -t arr < <( echo a; echo b; echo c )
或者(如果是bash
4.2 或更高版本)使用lastpipe
shell 选项:
shopt -s lastpipe
( echo a; echo b; echo c ) | readarray -t arr
请注意,默认情况下,第二种方法lastpipe
在交互式会话中不起作用。在这种情况下,首先运行
set +m
禁用“监视模式”。
答案2
也许尝试:
unset arr
printf %s\\n a b c | {
readarray arr
echo ${#arr[@]}
}
我预计它会起作用,但是当您走出管道末尾的最后一个{
shell上下文时,您将丢失变量值。这是因为管道中的每个单独进程都在子 shell中执行。所以你的东西因为同样的原因不起作用:; }
|
|
|
|
(
)
( arr=( a b c ) ) ; echo ${arr[@]}
...不 - 变量值设置在不同的shell 进程而不是您调用它的进程。
答案3
readarray
也可以从 stdin 读取,所以:
readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}