我正在运行 bash。
- 假设我有一个
mybinary
接受交互式用户输入的二进制文件。 - 假设
mybinary
将与会者姓名作为输入,直到用户键入q
并按下Enter(q
表示“退出”)。 <<EOF
我可以通过/包围输入来自动化 bash 脚本中的输入过程EOF
。例如,假设我想从数组输入预定义的用户输入myarray
。我可以:
#!/bin/bash
myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary
mybinary -f inputfile.txt -o outputfile.txt<<EOF
${myarray[0]}
${myarray[1]}
${myarray[2]}
${myarray[3]}
EOF
我测试了上面的内容,并且有效。但是如果有数百个(字符串)元素,${myarray[X]}
则为每个索引键入是很费力的。myarray
myarray
如何修改上面的 bash 脚本以循环遍历myarray
?
以下内容将不起作用,因为for
、do
和done
部分将被视为 的输入mybinary
:
#!/bin/bash
myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary
mybinary -f inputfile.txt -o outputfile.txt<<EOF
for element in "${myarray[@]}"
do
${myarray[0]}
${myarray[1]}
${myarray[2]}
${myarray[3]}
done
EOF
此外,我不能简单地放置for
循环大约调用mybinary
,因为我不想多次调用mybinary
。那么如何循环遍历数组以使用数组的元素作为输入mybinary
?
答案1
您可以printf
在数组中的每个条目之后添加换行符:
myarray=("Alice" "Bob" "Charlie" "q")
mybinary -f inputfile.txt -o outputfile.txt<<EOF
$(printf '%s\n' "${myarray[@]}")
EOF
正如 didal24 和 Steeldriver 指出的那样,您还可以使用管道而不是此处文档:
printf '%s\n' "${myarray[@]}" | mybinary -f inputfile.txt -o outputfile.txt
答案2
如果我很了解您的需求:
#!/bin/bash
myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary
mybinary -f inputfile.txt -o outputfile.txt < <(printf '%s\n' "${myarray[@]}")
如果您的二进制文件编码良好,则应该STDIN
透明地处理它。
答案3
要在 zsh 中每行打印一个数组的元素,您可以执行以下操作:
print -rC1 -- "$array[@]"
或者:
print -rNC1 -- "$array[@]"
用于 NUL 分隔的记录而不是行。
(print -rC1 -- $array
只会打印非空元素)。
bash
有一个print
内置函数(最初来自 ksh),但仅作为可选的可加载内置函数,并且不支持该-C
选项(也不支持-N
)。
printf '%s\n' "${array[@]}"
对于空数组无法正常工作,因为它打印一个空行(就好像数组有一个空元素)而不是根本不打印任何行。
bash(或一般的 POSIX shells)中的常见方法是定义一些辅助函数:
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
print0() { [ "$#" -eq 0 ] || printf '%s\0' "$@"; }
然后,你可以这样做:
println "${array[@]}" q | your-cmd
¹ 请注意,某些 POSIX shell(主要是 ksh88 和一些基于 pdksh 的 shell)没有printf
内置功能,因此无法输出大型列表,因为您很快就会达到参数大小的限制传递给外部命令。