bash 具有不同输入的映射文件行为
bash mapfile behavior with different inputs
我刚刚在 bash 中发现了 mapfile,当时 shellcheck 向我的代码推荐了它以捕获两个shell 参数来自 space 分隔的两个单词的字符串。但是,mapfile 似乎并不能始终如一地运行。例如,这按预期工作:
mapfile arr < myfile
数组 arr 填充了与 myfile 的行对应的条目。但是,这不起作用:
echo -e "hello\nworld" | mapfile arr
根本没有填充数组 arr。而且,这也不起作用:
echo "hello world" | mapfile -d ' ' arr
我不确定命令的标准输入来源为何会有所不同。我不知道可以区分输入的来源,文件还是管道。
有什么线索吗?
主持人注意:有人建议我的问题与 Read values into a shell variable from a pipe 重复。我不同意。那个问题中没有提到 mapfile,在 SO 搜索中也没有找到任何其他有用的 Q/A。此外,那个引用的问题没有涉及 shell 参数分配。因此,这个问题和答案很有价值。
从技术上讲,数组 是 被填充;问题是 mapfile
在 sub-process 中被调用,当它退出(返回到命令行)时,数组赋值丢失,即,您不能从 'up' 传递赋值sub-process 到 parent/calling 进程。
试试这些:
$ mapfile -d ' ' arr < <(echo -e "hello\nworld")
$ typeset -p arr
declare -a arr=([0]=$'hello\nworld\n')
$ mapfile -d ' ' arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello " [1]=$'world\n')
虽然这些 将 填充数组......您必须决定这是否是您期望在数组中显示的内容。也许以下更接近您的期望?
$ mapfile -t arr < <(echo -e "hello\nworld")
$ typeset -p arr
declare -a arr=([0]="hello" [1]="world")
$ mapfile -t arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello world")
在第二个命令集上,如果打算将每个单词解析为一个数组,那么也许可以将 mapfile
换成 read
?
$ read -ra arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello" [1]="world")
我刚刚在 bash 中发现了 mapfile,当时 shellcheck 向我的代码推荐了它以捕获两个shell 参数来自 space 分隔的两个单词的字符串。但是,mapfile 似乎并不能始终如一地运行。例如,这按预期工作:
mapfile arr < myfile
数组 arr 填充了与 myfile 的行对应的条目。但是,这不起作用:
echo -e "hello\nworld" | mapfile arr
根本没有填充数组 arr。而且,这也不起作用:
echo "hello world" | mapfile -d ' ' arr
我不确定命令的标准输入来源为何会有所不同。我不知道可以区分输入的来源,文件还是管道。
有什么线索吗?
主持人注意:有人建议我的问题与 Read values into a shell variable from a pipe 重复。我不同意。那个问题中没有提到 mapfile,在 SO 搜索中也没有找到任何其他有用的 Q/A。此外,那个引用的问题没有涉及 shell 参数分配。因此,这个问题和答案很有价值。
从技术上讲,数组 是 被填充;问题是 mapfile
在 sub-process 中被调用,当它退出(返回到命令行)时,数组赋值丢失,即,您不能从 'up' 传递赋值sub-process 到 parent/calling 进程。
试试这些:
$ mapfile -d ' ' arr < <(echo -e "hello\nworld")
$ typeset -p arr
declare -a arr=([0]=$'hello\nworld\n')
$ mapfile -d ' ' arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello " [1]=$'world\n')
虽然这些 将 填充数组......您必须决定这是否是您期望在数组中显示的内容。也许以下更接近您的期望?
$ mapfile -t arr < <(echo -e "hello\nworld")
$ typeset -p arr
declare -a arr=([0]="hello" [1]="world")
$ mapfile -t arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello world")
在第二个命令集上,如果打算将每个单词解析为一个数组,那么也许可以将 mapfile
换成 read
?
$ read -ra arr < <(echo "hello world")
$ typeset -p arr
declare -a arr=([0]="hello" [1]="world")