L’unica shell di cui sia a conoscenza che permetta di gestire bene file binari, ovvero contenenti il carattere NULL (’\0′) è zsh.
Ecco una breve dimostrazione fra le shell più comuni (dash, busybox ash e bash):
drizzt@janeway ~ % busybox sh -c 'a=$(printf "\001\002\000\003\004") ; echo -n "$a"' | hexdump -v -e '1/1 "%.2x "'
01 02 03 04
E che fine ha fatto lo 0? Si è perso!
drizzt@janeway ~ % dash -c 'a=$(printf "\001\002\000\003\004") ; echo -n "$a"' | hexdump -v -e '1/1 "%.2x "'
01 02 03 04
Esattamente come sopra
drizzt@janeway ~ % bash -c 'a=$(printf "\001\002\000\003\004") ; echo -n "$a"' | hexdump -v -e '1/1 "%.2x "'
01 02 03 04
Pure qui
Invece usando zsh, tutto cambia:
drizzt@janeway ~ % zsh -c 'a=$(printf "\001\002\000\003\004") ; echo -n "$a"' | hexdump -v -e '1/1 "%.2x "'
01 02 00 03 04
Ecco il carattere ‘\0′!
Anche le operazioni a stringa si possono effettuare pure avendo il NULL, per esempio contare il numero di caratteri nella stringa:
drizzt@janeway ~ % dash -c 'a=$(printf "\001\002\000\003\004") ; echo "${#a}"'
4
Con dash, bash e busybox sh conta 4 caratteri, mentre zsh ne conta, giustamente, 5:
drizzt@janeway ~ % zsh -c 'a=$(printf "\001\002\000\003\004") ; echo "${#a}"'
5
La stessa cosa con operazioni più complesse, come il reverse della stringa:
drizzt@janeway ~ % zsh -c 'a=$(printf "\001\002\000\003\004") ; echo -n "${(j::)${(@Oa)${(s::):-$a}}}"' | hexdump -v -e '1/1 "%.2x "'
04 03 00 02 01