Neulich musste ich in PHP-Skript schreiben, das unter anderem einen Link auf einer Videodatei erzeugen sollte. Aus zunächst unerfindlichen Gründen wollte und wollte das nicht funktionieren. Den Pfad mit "print()" auszugeben, gab aber auch keinen weiteren Aufschluss über das Problem, alles sah vollkommen normal und korrekt aus:
/sites/www.admin-magazin.de/files/S24142/01.mp4
Sehen Sie hier ein Problem? Ich jedenfalls nicht. Um ganz sicherzugehen, kopierte ich den Pfad dann in den Editor, um ihn noch einmal zeichenweise mit dem aus dem anderen Terminal kopierten Pfad des Dateisystems zu vergleichen. Da war dann auch schon der Fehler. In Wirklichheit sah der String nämlich so aus:
/sites/www.admin-magazin.de/files/S24142/<feff>01.mp4
FEFF ist als Unicode-Zeichen der sogenannte Byte Order Mark (BOM), der die Byte-Reihenfolge (Big/Little Endian) einer Unicode-Datei kennzeichnet, im konkreten Fall der UTF-8-Datei in der die Pfadinformationen gespeichert waren. Das Kommando "file" verriet weiterhin, dass die von den Benutzern hochgeladenen Dateien unterschiedlich kodiert waren, je nachdem, welches Betriebssystem und welchen Editor sie benutzt hatten.
find -name "parts.txt" | xargs file ./S24128/parts.txt: ASCII text, with CRLF line terminators ./S23774/parts.txt: ASCII text ./S22010/parts.txt: UTF-8 Unicode text ./S24125/parts.txt: ASCII text, with CRLF line terminators ./S24175/parts.txt: UTF-8 Unicode (with BOM) text ./S24177/parts.txt: UTF-8 Unicode (with BOM) text, with CRLF lineterminators
Wie man sieht, ein bunter Zoo von Zeichencodierungen, mit etwa allem, was es heute gibt. Fehlt nur noch EBCDIC, aber wenigstens verwendet hier niemand einen IBM-Großrechner...
Ist das Problem erst einmal erkannt, lässt es sich recht leicht lösen. Zum Beispiel entfernt der folgende Sed-Aufruf den Byte Order Mark aus der Datei:
sed -i -e '1s/^\xEF\xBB\xBF//' Datei
Alternativ kann dies auch das kleine Tool "bomstrip" erledigen, das zum Beispiel in den Repositories von Ubuntu-Distributionen enthalten ist.