Representando/citando NUL en la línea de comando

Representando/citando NUL en la línea de comando

¿Se puede \0utilizar 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 \0parece 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: \0puede 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 \0como 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 \0en la línea de comando para que, por ejemplo, echola 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 zshshell 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, echolas 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 -ebandera.

Entonces:

echo '\0'

o:

echo -e '\0'

Puede provocar echoque se genere el carácter NUL seguido del carácter LF.

Con zsh,

echo $'\0'

pasa el carácter NUL al echointegrado.

/bin/echo $'\0'

No funcionaría porque /bin/echoesejecutado, 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$

información relacionada