Attempt 1xargs -I '{}' -0 -n 1 myprogram --arg '{}' --other-optionsBut that does not preserve zero bytes. Also the program may run multiple times. But instead of failing in case of zero byte creeping into stdin, it runs program multiple times.Attempt 2myprogram --arg `cat` --other-optionsBut that does not preserve trailing whitespace.Attempt 3bash -c 'read -r -d  INPUT ; myprogram --arg $INPUT --other-options'Seems to mess with terminal, also fails to preserve trailing whitespace.How do I do it properly, reliably, readably, compatibly?
How do I turn entire stdin into a command line argument verbatim?
bash;shell script;command line;stdin
It is impossible to have NUL bytes in command line arguments, so the question is what do you want to happen in case there are NUL bytes in the standard input.As you've noted, your candidate solution #1 runs the command multiple times in this case. That's not ideal. But there is no ideal solution that lets you handle true binary input. As I see it, your only other reasonable options here are to:delete the NUL bytes and proceedinsert tr -d '\0' | before xargstranslate the NUL bytes to something else and proceedinsert tr '\0'  something-else | before xargs (if something-else is a single byte)abort and bail in case there are NUL byteswith bash or ksh93 (except if the input contains a single null byte at the end, in which case it is silently deleted):{ 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}with zsh (and not with other shells such as bash, ksh or dash):input=$(<&0)  if [[ $input != *$'\0'* ]]; then    printf %s $input | xargs ;  else    echo 1>&2 Null bytes detected, bailing out    exit 2  fiOr use a temporary file.truncate the input after the first NUL byteinsert tr '\0\n' '\n\0' | head -n 1 | tr '\0\n' '\n\0' before xargs (assuming your head is null-safe)