On 12/9/24 03:34, Christoph Anton Mitterer wrote:
Hey.

Not sure whether this has been brought up before (at least a quick
search didn't reveal anything in the bug tracker or the archive).

xargs -0 still executes the command even when no terminating NUL has
been found in the (last) line.

As shown by e.g. the following script foo.sh:
    #!/bin/sh
    printf '/'
    if [ -n "$1" ]; then
        kill -9 "$$"
    fi
    printf 'tmp\000'

Which yields:
$ ./foo.sh | xargs -0 printf '»%s«\n'
»/tmp«
$ ./foo.sh kill | xargs -0 printf '»%s«\n'
»/«

The above test case can be simplified to the cases:

  $ printf 'hello' | xargs -0 printf "<%s>\n"
  <hello>

  $ printf 'hello\0' | xargs -0 printf "<%s>\n"
  <hello>

  $ printf 'hello\0world' | xargs -0 printf "<%s>\n"
  <hello>
  <world>

  $ printf 'hello\0world\0' | xargs -0 printf "<%s>\n"
  <hello>
  <world>

This means xargs(1) does currently not care whether the last entry is
'\0'-terminated or not.

This, of course, can lead to catastrophic behaviour if the command
that's piped into xargs is killed at the wrong time.
Just consider an example like:
$ ./foo.sh kill | xargs -0 rm -rf


I think the proper behaviour would be to do both,
- not include any non-terminated line (e.g. NUL or LF)
   though I would say it could execute for all other, properly
   terminated lines, that have been read up to that point
- perhaps, if a non-terminated line was found, exit with some special
   exit status (see below)


This problem is even mentioned in the most recent 2024 edition of
POSIX:
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/xargs.html

FUTURE DIRECTIONS
A future version of this standard may require that, when the -0
option is specified, if the standard input is not empty and does not
end with a null byte, xargs ignores the trailing non-null bytes.

I'll ask at the WG, whether it wouldn't be better to give an error
instead of ignoreing it.

IMO the above, current bahavior is not that terribly bad, but rather
quite good and consistent.

A question in this context may rather be how xargs(1) should handle empty, i.e.,
Zero-length, entries: 'hello\0\0world'.  But I don't see much to improve
or change at this point.

Have a nice day,
Berny

Reply via email to