尝试1
xargs -I '{}' -0 -n 1 myprogram --arg '{}' --other-options
但这并不能保留零字节。该程序也可能运行多次。但是,它不会在零字节进入标准输入的情况下失败,而是多次运行程序。
尝试2
myprogram --arg "`cat`" --other-options
但这并不能保留尾随空白。
尝试3
bash -c 'read -r -d "" INPUT ; myprogram --arg "$INPUT" --other-options'
似乎弄乱了终端,也无法保留尾随空格。
如何正确、可靠、可读、兼容地做到这一点?
答案1
命令行参数中不可能有 NUL 字节,所以问题是如果出现这种情况你希望发生什么是标准输入中的 NUL 字节。
正如您所指出的,在这种情况下,您的候选解决方案#1 多次运行该命令。这并不理想。但没有理想的解决方案可以让您处理真正的二进制输入。在我看来,您唯一的其他合理选择是:
- 删除 NUL 字节并继续
- 插入
tr -d '\0' |
之前xargs
- 插入
- 将 NUL 字节转换为其他字节并继续
- 插入
tr '\0' something-else |
之前xargs
(如果something-else
是单个字节)
- 插入
如果存在 NUL 字节,则中止并保释
使用 bash 或 ksh93(除非输入末尾包含单个空字节,在这种情况下它将被静默删除):
{ read -r -d '' input; if [ "$(wc -c)" = 0 ]; then printf %s "$input" | xargs …; else echo 1>&2 "Null bytes detected, bailing out" exit 2 fi }
使用 zsh(而不是使用其他 shell,例如 bash、ksh 或 dash):
input=$(<&0) if [[ $input != *$'\0'* ]]; then printf %s "$input" | xargs …; else echo 1>&2 "Null bytes detected, bailing out" exit 2 fi
- 或者使用临时文件。
在第一个 NUL 字节之后截断输入
- 插入
tr '\0\n' '\n\0' | head -n 1 | tr '\0\n' '\n\0'
之前xargs
(假设你head
是空安全的)
- 插入