Darstellen/Zitatieren von NUL in der Befehlszeile

Darstellen/Zitatieren von NUL in der Befehlszeile

Kann \0auf der Befehlszeile verwendet werden?

Hintergrund

Zum Testen von Sonderfällen in GNU Parallel war ich neugierig, ob alle Zeichen in der Befehlszeile korrekt in Anführungszeichen gesetzt wurden. Die meisten davon sind:

perl -e 'print pack ("c*",1..255,10)' | parallel -k echo | md5sum
d03484ca75b3e38be411198d66bf4611  -
perl -e 'print pack ("c*",1..255,10)' | md5sum
d03484ca75b3e38be411198d66bf4611  -

Scheint aber \0schwierig zu sein (hier illustriert mit 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)

Das zweite Beispiel kann ich einigermaßen rechtfertigen: \0kann als EOS interpretiert werden, aber das sollte dann auch in Beispiel 4 der Fall sein. Beispiel 3 betont, dass GNU Parallel es nicht \0als EOS sieht, sondern an weitergibt bash.

Können Sie erklären, was los ist? Besonders Fall 4 gibt mir Rätsel auf.

Und noch wichtiger:

Gibt es eine Möglichkeit, \0in der Befehlszeile Anführungszeichen zu setzen, sodass EG echosie sieht?

Antwort1

Bei der Ausführung eines Befehls ist die Liste der Argumente eine Liste von Zeigern auf NUL-terminierte Zeichenfolgen, die an den execve()Systemaufruf übergeben werden (genau wie die Umgebungsvariablen, die die andere Liste von NUL-terminierten Zeichenfolgen sind, die an übergeben werden execve()).

Als Ergebnis werden Argumente und Umgebungsvariablen vonhingerichtetBefehle dürfen kein NUL-Zeichen enthalten.

Ausnahmen hiervon sind integrierte Funktionen und Funktionen in der zshShell, deren Argumente alles enthalten können (diese sind integriert, sodass der execve()Systemaufruf nicht beteiligt ist).

Sie können Daten mit NUL-Zeichen über stdin (oder einen anderen Dateideskriptor) oder in jedem beliebigen Dateityp übergeben. Oder ein Befehl versteht eine bestimmte Form der Kodierung.

Beispielsweise echoverstehen UNIX-konforme Implementierungen \0(die beiden Zeichen Backslash und Null) als NUL-Zeichen. Einige andere Implementierungen tun dies nur, wenn das -eFlag übergeben wird.

Also:

echo '\0'

oder:

echo -e '\0'

Kann echozur Ausgabe des NUL-Zeichens gefolgt vom LF-Zeichen führen.

Mit zsh,

echo $'\0'

übergibt das NUL-Zeichen an das echointegrierte.

/bin/echo $'\0'

Würde nicht funktionieren, weil /bin/echoisthingerichtet, daher darf sein Argument kein NUL-Zeichen enthalten.

Zu Ihrer Frage zu Punkt 4. Es ist nur so, dass Bash diese NUL-Zeichen ignoriert. Einige andere Shells verhalten sich anders.

$ 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$

verwandte Informationen