Bash 和 dash 中的 Here-documents 不支持这一点。您不能在变量中存储空值,它们会从命令替换中删除,您不能按字面意思写入,并且不能在 here-document 中使用 ANSI-C 引用。两种 shell 都不是空友好的,如果进入,它们通常被视为(C 风格)字符串终止符。
您有几个选择:使用真实文件、使用 zsh、使用进程替换或使用标准输入。
您可以在 zsh 中做您想做的事情,这对 null 更加友好。
zsh% null=$(printf '\x00')
zsh% hexdump -C <<EOT
heredoc> a${null}b${null}
heredoc> EOT
00000000 61 00 62 00 0a |a.b..|
00000005
Run Code Online (Sandbox Code Playgroud)
请注意,heredocs 有一个隐式终止换行符,这可能是不可取的(它将是shuf最终空值之后的额外字段)。
对于 Bash,您可以使用几乎等同于您的 heredoc 的进程替换结合printf或echo -e创建内联空值:
bash$ hexdump -C < <(
printf 'item 1\x00item\n2\x00'
)
00000000 69 74 65 6d 20 31 00 69 74 65 6d 0a 32 00 |item 1.item.2.|
0000000e
Run Code Online (Sandbox Code Playgroud)
这不一定完全等同于 here-document,因为这些文件通常由 shell 秘密放入真实文件中(这对可查找性很重要,等等)。
由于您可能想要禁止终止换行符,因此您甚至不能在那里的命令内部使用heredoc - 它必须printf/echo -ne如果安全才能对输出进行细粒度控制。
您不能在 dash 中进行进程替换,但在任何 shell 中,您都可以从子 shell 输入标准输入:
dash$ (
printf 'item 1\x00'
printf 'item\n2\x00'
) | hexdump -C
00000000 69 74 65 6d 20 31 00 69 74 65 6d 0a 32 00 |item 1.item.2.|
0000000e
Run Code Online (Sandbox Code Playgroud)
shuf默认情况下很高兴从标准输入中读取数据,因此按照我的理解,这应该适用于您的具体用例。如果您有更复杂的命令,位于管道的右侧可能会引入一些与作用域混淆的元素。
最后,您可以使用printf并使用它而不是 here-document将您的数据写入一个真实的文件。该选项已在另一个答案中介绍。您需要确保事后清理文件,并且mktemp如果存在任何实时安全问题,可能需要使用或类似(如果可用)来创建安全文件名。
谢谢你们。让我根据你们所有人发布一个答案,也许最适合我。
这个剧本很好地工作在bash和破折号,没有需要真正的文件或在bash进程替换,无需要额外的缓慢外部程序调用,即使你并不需要担心实体的任何逃生的问题,因为%s在C的printf,但你应该仍然要注意在你的 shell 中字符串转义。
#!/bin/sh
printf '%s\0' "[tag1]
key1=value1
key2=value2
[/tag1]
" "[tag2]
key3=value3
key4=value4
[/tag2]
" | shuf --zero-terminated
#also see man printf(1)
Run Code Online (Sandbox Code Playgroud)
对于shuf只(不原意一般这里文档二选一):
shuf --echo "[tag1]
key1=value1
key2=value2
[/tag1]" "[tag2]
key3=value3
key4=value4
[/tag2]"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
861 次 |
| 最近记录: |