Wie kann ich die Robustheit meines Shell-Skripts beim Umgang mit Dateien testen?

11

Ich habe ein Shell-Skript geschrieben, das einige "normale" Dateinamen verarbeitet, aber ich habe gelesen, warum mein Shell-Skript Leerzeichen oder andere Sonderzeichen verschluckt. und warum Sie die Ausgabe von ls nicht analysieren sollten und ich möchte, dass sie robuster ist und alle gültigen Dateinamen (und / oder Verzeichnisnamen) verarbeitet. Wie kann ich eine Testumgebung mit Dateien und Verzeichnissen erstellen, für die mein Skript ausgeführt werden soll?

Jeff Schaller
quelle

Antworten:

11

Erstellen Sie ein separates Verzeichnis zum Abspielen (hauptsächlich zur späteren Bereinigung). Dies verwendet den Wert von, $TMPDIRwenn es gesetzt ist, andernfalls /tmp:

mkdir "${TMPDIR-/tmp}/testing"
cd "${TMPDIR-/tmp}/testing"

Erstellen Sie Dateien, die getrennt sind, aber aufgrund von Leerzeichen (Leerzeichen, Tabulator, Zeilenumbruch, Wagenrücklauf, Rücktaste) ähnlich aussehen:

touch -- a b 'a ' 'b ' 'a b' 'a  b' $'a\bb'
touch -- a$'\xe2\x80\x82'b a$'\xe2\x80\x83'b a$'\t'b a$'\n'b a$'\r'b

Gutschrift für das oben genannte an Patrick . Die beiden Hex-Code-Leerzeichen sind UTF-8-Raumtrennzeichen, die als Nuss und Hammel bekannt sind . "Im bidirektionalen Kontext fungiert es als Leerraum und wird nicht gespiegelt. Die Glyphen können unter Umständen mit 20 anderen Glyphen verwechselt werden."

Erstellen Sie eine einfache Datei und eine Datei, die auf die erste erweitert wird, wenn sie als Glob behandelt wird:

touch -- x '[x]' 

Gutschrift für das oben genannte an Wumpus Q. Wumbley .

In ähnlicher Weise:

touch -- 'a?b' 'a*b'

Gutschrift für das oben genannte an dave_thompson_085 in den Kommentaren hier.

touch -- foo\`echo\ malicious\`bar

Gutschrift für das oben Genannte zu godlygeek .

Ein Dateiname, der bei Auswertung in einem Shell-Kontext zu etwas anderem (und möglicherweise willkürlicher Ausführung!) Erweitert wird:

touch '$( echo boom )'

Verwenden:

touch -- single\'quote double\"quote back\\slash

Versuche zu fangen, einen Dateinamen in Anführungszeichen zu setzen, ohne Anführungszeichen zu entkommen.

touch -- -a -b -c -r -R - a=x

Gutschrift für das oben genannte an Stéphane Chazelas .

Erstellen Sie eine Named Pipe und einen Symlink (um Dateien zu erstellen, die nicht "normal" sind):

mkfifo fifo
ln -s a alink

Erstellen Sie Unterverzeichnisse, in deren Namen verschiedene Leerzeichen enthalten sind, sowie darin enthaltene Token-Dateien:

mkdir subdir "subdir 1" "subdir 2" "subdir 3 " subdir$'\n'4
touch subdir/file0 "subdir 1"/file1 "subdir 2"/file2 "subdir 3 "/file3 subdir$'\n'4/file4

Erstellen Sie Dateinamen, die nur einen Dateinamen enthalten *(möglicherweise problematisch zu entfernen), der nur aus einem (regulären!) Leerzeichen, einem toten symbolischen Link, einem symbolischen Link, der sich auf sich selbst schleift, und einem Unterverzeichnis mit einem Link zurück zum übergeordneten Verzeichnis besteht:

touch -- '*' '**' '***' ' '

ln -s /does/not/exist dead

ln -s loop loop

mkdir subdir_with_link
(cd subdir_with_link && ln -s .. parent)

Weitere verschiedene Dateinamen. Die letzten beiden sind Unicode für "Bruchschrägstrich" und "Teilungsschrägstrich".

touch -- '(' '!' '!!'  $'\xe2\x81\x84' $'\xe2\x88\x95'

Ideen von Scott :

touch -- '-' '--' ';' '&' '|' '<' '>' '$' ')' '{' '}' = \\ '!' '#' '{a,b}'

Charaktere, die in einigen Regionen harmlos, in anderen jedoch gefährlich sind:

touch $'X\xa0Y' # non-breaking space in iso8859-1 which is considered
                # "blank" and "space" in some locales

touch $'\xa3\x5c' $'\xa3\x60' # α and ε in BIG5 or BIG5-HKSCS charset, but
                              # �\ and �` in ASCII

Zeichen, die in einigen Regionen gleich sortiert sind:

touch   # sorts the same in GNU locales, order non-deterministic.

Dateien, die dem .[!.]* *Glob entkommen (manchmal zum Erweitern von versteckten und nicht versteckten Dateien verwendet):

touch ..foo ...
Jeff Schaller
quelle
Die Ironie eines "Kommentar" -Kommentars lenkt ab. Wollen Sie Erklärungen hinzufügen, was die verschiedenen Befehle tun?
Jeff Schaller
1
Ja, bitte beschreiben Sie die Testfälle, die Sie am häufigsten erstellen. Einige davon sind solche, die wie ein Unicode-Zeichen aussehen.
Muru
1
Ich würde hinzufügen a?bund a*b(natürlich zitiert). @muru: Byte-Sequenzen E2 80 82/83 sind die UTF-8-Codierung von U + 2002 EN SPACE und U + 2003 EM SPACE
dave_thompson_085
Einige böse Genies arbeiten dort: -c
user207673
Es könnte interessant sein, damit zu spielen, -und --je nach den Anforderungen des Skripts sollte es möglicherweise unmöglich sein, ohne einen Lead darauf zuzugreifen ./. Und ich bin überrascht , dass es so wenige sind mit nicht-glob Shell Sonderzeichen, wie ;, &, |, <, >, $, (, ), {, }, =, \, !, und #- zum Beispiel {a,b}.
Scott