The following outputs only $ with a newline.
{ i=0; while [ $i -lt 89 ]; do printf $i\\0; : $(( i++ )); done; } |
xargs -0 -I $ printf '%s\n' $
The problem is two fold. The first is that strnsubst gives up on
substituting since replstr is greater than maxsize. This should likely
cause an error, but I don't know the preferred way to do that.
The second problem is that count needs to be incremented so that the
utility will be run after a null byte. The patch below comes from
FreeBSD. https://svnweb.freebsd.org/base?view=revision&revision=142604
That commit also moved a count++. While I don't believe that it is
necessary; but it also doesn't hurt. I believe it makes the code easier
to follow as now all paths immediately short circuit to addch except
null and EOL.
Index: xargs.c
===================================================================
RCS file: /cvs/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.29
diff -u -p -r1.29 xargs.c
--- xargs.c 18 Apr 2015 18:28:38 -0000 1.29
+++ xargs.c 27 Sep 2015 06:20:01 -0000
@@ -255,11 +255,9 @@ parse_input(int argc, char *argv[])
ch = getchar();
if (isblank(ch)) {
/* Quotes escape tabs and spaces. */
- if (insingle || indouble)
+ if (insingle || indouble || zflag)
goto addch;
hasblank = 1;
- if (zflag)
- goto addch;
goto arg2;
}
@@ -274,15 +272,22 @@ parse_input(int argc, char *argv[])
}
goto arg1;
case '\0':
- if (zflag)
+ if (zflag) {
+ /*
+ * Increment 'count', so that nulls will be treated
+ * as end-of-line, as well as end-of-argument. This
+ * is needed so -0 works properly with -I and -L.
+ */
+ count++;
goto arg2;
+ }
goto addch;
case '\n':
+ if (zflag)
+ goto addch;
hasblank = 1;
if (hadblank == 0)
count++;
- if (zflag)
- goto addch;
/* Quotes do not escape newlines. */
arg1: if (insingle || indouble)