我想shuf --zero-terminated
使用此处文档对多行字符串执行操作。
答案1
Bash 和 dash 中的 Here-documents 不支持这一点。您不能在变量中存储 null,它们会从命令替换中删除,您不能按字面意思编写 null,并且不能在此处文档中使用 ANSI-C 引用。这两个 shell 都不是 null 友好的,如果进入的话,它们通常被视为(C 风格)字符串终止符。
您有几个选择:使用真实文件、使用 zsh、使用进程替换或使用标准输入。
你能在 zsh 中完全按照您想要的方式进行操作,这对空值更加友好。
zsh% null=$(printf '\x00')
zsh% hexdump -C <<EOT
heredoc> a${null}b${null}
heredoc> EOT
00000000 61 00 62 00 0a |a.b..|
00000005
请注意,尽管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
这不一定完全等同于此处文档,因为这些文件通常由 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
shuf
默认情况下很乐意从标准输入中读取内容,因此据我了解,这应该适用于您的具体用例。如果您有更复杂的命令,则位于管道的右侧可能会引入一些与范围界定混淆的元素。
最后,您可以使用该文件将数据写入真实文件printf
,而不是使用此处文档。该选项已包含在另一个答案。您需要确保事后清理文件,并且可能想要使用mktemp
或类似的内容(如果存在任何实时安全问题)可用于创建安全文件名。
答案2
谢谢你们。让我发布一个基于你们所有人的答案,也许对我来说是最好的。
该脚本在 bash 和 dash 中运行良好,不需要真实文件或bash 中的进程替换,不需要额外缓慢的外部程序调用,甚至您不需要担心实体中的任何转义问题,%s
如打印输出,但你仍然应该注意 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)
为了shuf
仅(无意于一般此处文档的替代方案):
shuf --echo "[tag1]
key1=value1
key2=value2
[/tag1]" "[tag2]
key3=value3
key4=value4
[/tag2]"
答案3
我认为你不能在heredoc中做你想做的事。然而,使用起来很简单echo
,如下例所示:
$ cat demo
#!/bin/bash
echo -ne "one\0" > outfile
echo -ne "two\0" >> outfile
echo -ne "three\0" >> outfile
$ ./demo
$ od -a outfile
0000000 o n e nul t w o nul t h r e e nul
0000016
$
答案4
我最终使用了一个“技巧”
cat <<EOS | cat - <(echo -e "\0") | most
{
"version":"1.1",
"gelf-toekn":"SOMETHIN",
"host": "api.ivsdev.net",
"short_message": "foo",
"full_message": "bar",
"level": 1
}
EOS
第一个定界符猫通过管道输送到第二个定界符猫中,第二个定界符猫将其与空字节连接起来。