Using binary data as a parameter in bash - any way to allow nuls?
There is no way to pass a null byte in the parameter of a command. This is not because of a limitation of bash, although bash has this limitation as well. This is a limitation of the interface to run a command: it treats a null byte as the end of the parameter. There's no escaping mechanism.
Most shells don't support null bytes in variables or in the arguments of functions and builtins. Zsh is a notable exception.
$ ksh -c 'a=$(printf foo\\0bar); printf "$a"' | od -t x1
0000000 66 6f 6f
0000003
$ bash -c 'a=$(printf foo\\0bar); printf "$a"' | od -t x1
0000000 66 6f 6f 62 61 72
0000006
$ zsh -c 'a=$(printf foo\\0bar); printf "$a"' | od -t x1
0000000 66 6f 6f 00 62 61 72
0000007
But even with zsh, if you attempt to pass a parameter to an external command, then anything following a null byte is ignored — not by zsh but by the kernel.
$ zsh -c 'a=$(printf foo\\0bar); /usr/bin/printf "$a"' | od -t x1
0000000 66 6f 6f
0000003
If you want to pass null bytes to a program, you need to find some way other than a command line parameter.
head -c 512 binaryFile.dd | myProgram --read-parameter2-from-stdin parameter1
myProgram --read-parameter2-from-file=<(head -c 512 binaryFile.dd) parameter1
bash
is not best suited to handle binary data directly.
Either use the binary data with a file, either use the hexadecimal string representing your data.
To convert in hexadecimal you can use hexdump
, xxd
, od
.
For example to convert a 512 bytes to an hexadecimal string, use
xxd -ps -c 512 file.bin
To convert it back to binary use
echo "$myhexstring" | xxd -r -ps > file.bin