Vi.*_*Vi. 2 command-line bash shell-script stdin
xargs -I '{}' -0 -n 1 myprogram --arg '{}' --other-options
Run Code Online (Sandbox Code Playgroud)
但这不会保留零字节。此外,该程序可能会运行多次。但是,它不会在零字节进入标准输入的情况下失败,而是多次运行程序。
myprogram --arg "`cat`" --other-options
Run Code Online (Sandbox Code Playgroud)
但这不会保留尾随空格。
bash -c 'read -r -d "" INPUT ; myprogram --arg "$INPUT" --other-options'
Run Code Online (Sandbox Code Playgroud)
似乎与终端混淆,也无法保留尾随空格。
我如何正确,可靠,可读,兼容地做到这一点?
在命令行参数中不可能有 NUL 字节,所以问题是如果标准输入中有NUL 字节,你想发生什么。
正如您所指出的,在这种情况下,您的候选解决方案 #1 会多次运行该命令。这并不理想。但是没有理想的解决方案可以让您处理真正的二进制输入。在我看来,您在这里唯一的其他合理选择是:
tr -d '\0' |
之前插入xargs
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
}
Run Code Online (Sandbox Code Playgroud)使用 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
Run Code Online (Sandbox Code Playgroud)在第一个 NUL 字节之后截断输入
tr '\0\n' '\n\0' | head -n 1 | tr '\0\n' '\n\0'
之前插入xargs
(假设您head
是空安全的)