On Wed, Nov 25, 2009 at 02:35:51PM +0100, Antonio Macchi wrote: > it sounds strange, beacuse > > $ find . -print0 | while read -d $'\x00'; do touch "$REPLY"; done > > works fine. > > > but if I try to "output" $'\x00', I can't.
There's a lot going on here, so I'll try to cover it as best I can. When you run read -d $'\x00' what you're really doing is setting up a bunch of C-strings in memory like this: +-+-+-+-+--+- |r|e|a|d|\0| +-+-+-+-+--+- +-+-+--+- |-|d|\0| +-+-+--+- +--+--+- |\0|\0| +--+--+- That is, you're explictly creating a C-string whose content is a NUL byte, and then it ends with another NUL byte. When the read command gets around to reading these strings to see what its arguments are, it sees the last string above as '' (an empty string), because the first NUL it sees marks the end of the content. read -d $'\x00' is completely equivalent to read -d '' and you may find the latter to be a bit less typing. The next issue is that you _can_ output a NUL byte, for example by using printf: imadev:~$ printf 'foo\0' | od -t x1 0000000 66 6f 6f 0 We don't pass a literal NUL byte to printf, because it would get lost in the C-string (interpreted as an end-of-string marker). We send a backslash-zero pair instead, and printf knows to treat that as a NUL when writing its output. In general, NULs can be read and written, and stored in files, but they can't be stored in a bash variable. Nor can they appear in a command argument. A NUL in a command argument causes the argument to be truncated as you'd expect if you're a C programmer: imadev:~$ echo $'foo\0bar' foo Contrast that with the printf '\0' command.