¿Se puede \0
utilizar en la línea de comando?
Fondo
Para probar casos extremos en GNU Parallel, tenía curiosidad por saber si todos los caracteres estaban entre comillas correctamente en la línea de comando. La mayoría de ellos son:
perl -e 'print pack ("c*",1..255,10)' | parallel -k echo | md5sum
d03484ca75b3e38be411198d66bf4611 -
perl -e 'print pack ("c*",1..255,10)' | md5sum
d03484ca75b3e38be411198d66bf4611 -
Pero \0
parece complicado (aquí ilustrado con A\0B\n
):
perl -e 'print pack ("c*",65,0,66,10)' | wc -c
4 (A\0B\n)
perl -e 'print pack ("c*",65,0,66,10)' | parallel echo | wc -c
2 (A\n)
perl -e 'print pack ("c*",65,0,66,10)' | parallel --dry-run echo | wc -c
9 (echo A\0B\n)
perl -e 'print "echo ",pack ("c*",65,0,66,10)' | bash | wc -c
3 (AB\n)
Puedo justificar el segundo ejemplo: \0
puede interpretarse como EOS, pero ese también debería ser el caso en el ejemplo 4. El ejemplo 3 enfatiza que GNU Parallel no ve \0
como EOS, sino que lo pasa a bash
.
¿Puedes explicar qué está pasando? Especialmente el caso 4 me desconcierta.
Y más importante:
¿Hay alguna forma de citar \0
en la línea de comando para que, por ejemplo, echo
la vea?
Respuesta1
Al ejecutar un comando, la lista de argumentos es una lista de punteros a cadenas terminadas en NUL pasadas a la execve()
llamada del sistema (al igual que las variables de entorno, que es la otra lista de cadenas terminadas en NUL pasadas a execve()
).
Como resultado, los argumentos y las variables de entorno deejecutadoLos comandos no pueden contener el carácter NUL.
La excepción a esto son las funciones integradas y en el zsh
shell cuyos argumentos pueden contener cualquier cosa (éstas están integradas, por lo que la execve()
llamada al sistema no está involucrada).
Puede pasar datos con caracteres NUL a través de stdin (o cualquier otro descriptor de archivo) o en cualquier tipo de archivo. O algún comando comprende alguna forma de codificación.
Por ejemplo, echo
las implementaciones compatibles con UNIX entienden \0
(los dos caracteres barra invertida y cero) como carácter NUL. Algunas otras implementaciones hacen eso solo cuando se pasa la -e
bandera.
Entonces:
echo '\0'
o:
echo -e '\0'
Puede provocar echo
que se genere el carácter NUL seguido del carácter LF.
Con zsh
,
echo $'\0'
pasa el carácter NUL al echo
integrado.
/bin/echo $'\0'
No funcionaría porque /bin/echo
esejecutado, por lo que su argumento no puede contener el carácter NUL.
En cuanto a tu pregunta del punto 4. Es solo que bash ignora esos caracteres NUL. Algunos otros caparazones se comportan de manera diferente.
$ printf 'e\0cho a\0b\n' | bash |& sed -n l
ab$
$ printf 'e\0cho a\0b\n' | ksh |& sed -n l
ksh: syntax error at line 1: `zero byte' unexpected$
$ printf 'e\0cho a\0b\n' | zsh |& sed -n l
zsh: command not found: e$
$ printf 'e\0cho a\0b\n' | rc |& sed -n l
line 1: warning: null character ignored$
line 1: warning: null character ignored$
ab$