Welche Zeichen müssen in Dateien ohne Anführungszeichen maskiert werden?

12

Ich habe eine browserbasierte Shell / ein browserbasiertes Terminal, das Bash-Befehle ausführt, und ich entkomme Leerzeichen, aber es stellt sich heraus, dass auch Klammern maskiert werden müssen. Welche anderen Zeichen müssen für Dateinamen, die nicht in Anführungszeichen stehen, maskiert werden?

jcubic
quelle
Es ist überhaupt nicht klar, was Sie versuchen zu tun. Und was hat Autocompletion mit irgendetwas zu tun?
Michael Vehrs
@MichaelVehrs Ich habe einen Befehl mv filename filename-fooin Bash. Welche Zeichen muss ich außer Leerzeichen und Klammern entkommen?
Jcubic
@MichaelVehrs hat die Erwähnung der automatischen Vervollständigung entfernt.
Jcubic
Grundsätzlich alle Shell-Metazeichen wie Leerzeichen, Shell-Globs und Verlaufsereignisse. Aus diesem Grund sollten Sie den gesamten Dateinamen angeben, anstatt einzelne Zeichen zu maskieren : mv "$filename" "$newname".
Michael Vehrs
@MichaelVehrs Ich weiß, dass das Zitieren das Problem mit dem Escapezeichen lösen wird, aber ich muss den Dateinamen ohne Anführungszeichen verwenden. Ich habe Terminalemulator und es sollte funktionieren, wenn Benutzer keine Anführungszeichen verwenden.
Jcubic

Antworten:

21

Die einfache Lösung besteht darin, ein einfaches Anführungszeichen ( ') am Anfang und ein weiteres einfaches Anführungszeichen am Ende einzufügen und jedes 'Zeichen im Dateinamen durch die 4-stellige Sequenz zu ersetzen '\''. Alle Zeichen verlieren ihre besondere Bedeutung innerhalb einer Zeichenfolge in einfachen Anführungszeichen, mit Ausnahme von sich 'selbst, das das Ende der Zeichenfolge markiert. Die Sequenz '\''beendet das Literal in einfachen Anführungszeichen, unmittelbar gefolgt von einem einfachen Anführungszeichen in Anführungszeichen und öffnet ein neues Literal in einfachen Anführungszeichen. Also der Dateiname

This file's name has some weird characters!
Will you manage to escape them?

kann wie folgt zitiert werden:

somecommand 'This file'\''s name has some weird characters!
Will you manage to escape them?'

Doppelte Anführungszeichen haben komplexere Escape-Regeln und erlauben Ihnen nicht, ein Ausrufezeichen einzufügen, !wenn die Verlaufssubstitution aktiviert ist. Daher werde ich sie nicht weiter betrachten.

Ein alternativer Ansatz besteht darin, Zeichen mit Backslashes zu schützen. Dies funktioniert für alle Zeichen außer Zeilenumbrüchen. Für eine neue Zeile ist es die einzige Lösung, sie in einfache Anführungszeichen (oder doppelte Anführungszeichen) zu setzen. Wenn Sie die Anzahl der Backslashes minimieren möchten, um dem Benutzer den angegebenen Namen anzuzeigen, können Sie ihn auf Stellen beschränken, an denen der Backslash benötigt wird. Je mehr Backslashes Sie jedoch weglassen, desto mehr riskieren Sie, einen zu vergessen, der benötigt wird. Buchstaben, Ziffern und Nicht-ASCII-Zeichen sind immer in Ordnung¹. Zitieren Sie Leerzeichen und Interpunktion, wenn Sie sich nicht sicher sind.

Bei einer typischen Shell (ksh, bash oder zsh) müssen Sie zumindest unter bestimmten Umständen die folgenden Zeichen zitieren.

  • Leerzeichen (Leerzeichen, Tabulator, Zeilenumbruch - Beachten Sie, dass Zeilenumbrüche nicht mit einem Backslash angegeben werden können).
  • ! - Erweiterung der Geschichte.
  • " - Shell-Syntax.
  • #- Kommentarstart, wenn Leerzeichen vorangestellt sind; zsh Wildcards.
  • $ - Shell-Syntax.
  • & - Shell-Syntax.
  • ' - Shell-Syntax.
  • (- sogar mitten in einem Wort: ksh Extended Globs (auch in Bash und Zsh erhältlich); zsh Wildcards.
  • )(siehe ()
  • * - sh Wildcard.
  • , - nur innerhalb der Klammererweiterung.
  • ; - Shell-Syntax.
  • < - Shell-Syntax.
  • = - in zsh, wenn es am Anfang eines Dateinamens steht (Dateinamenerweiterung mit PATH-Suche).
  • > - Shell-Syntax.
  • ? - sh Wildcard.
  • [ - sh Wildcard.
  • \ - Shell-Syntax.
  • ] - Sie können davonkommen, wenn Sie es nicht zitieren.
  • ^- Erweiterung der Geschichte; zsh Wildcard.
  • ` - Shell-Syntax.
  • { - Klammererweiterung.
  • | - Shell-Syntax.
  • } - muss in zsh entkommen, andere Schalen sind milder, wenn es keine passende Öffnungsstrebe gibt.
  • ~- Erweiterung des Home-Verzeichnisses am Anfang eines Dateinamens; zsh Wildcard; Immer sicher, wenn es das letzte Zeichen ist.

Einige weitere Zeichen können manchmal eine besondere Behandlung erfordern:

  • -ist nicht speziell für die Shell, aber wenn es am Anfang eines Befehlsarguments steht, zeigt es eine Option an. Es kann nicht mit Anführungszeichen geschützt werden, da sich die spezielle Behandlung im Befehl und nicht in der Shell befindet. Um einen Dateinamen zu schützen, der mit beginnt -, können Sie ihn vorlegen ./- auf diese Weise ist es immer noch dieselbe Datei, aber das Argument beginnt nicht mit- mehr mit.
  • .ist an sich nichts Besonderes, aber *Punktdateien sind standardmäßig von Globs ausgeschlossen .
  • :ist nicht speziell für die Shell, aber einige Befehle analysieren sie speziell, z. B. um eine entfernte Datei ( hostname:filename) anzugeben . In der Dokumentation des Befehls finden Sie Informationen zum Umgang mit Dateinamen, die Doppelpunkte enthalten.

¹ Es sei denn, der Benutzer hat alternative Verlaufserweiterungszeichen konfiguriert. Einige Muscheln erlauben dies. Dies ist ein weiterer Grund, einfache Anführungszeichen anstelle von Backslashes zu verwenden.

Gilles 'SO - hör auf böse zu sein'
quelle
Zumindest LFnur Zeilenumbrüche können in einigen Shells mit einem Backslash zitiert werden.
iBug
@iBug Nein. In jeder sh-ähnlichen Shell wird Backslash + Newline zu einer leeren Zeichenfolge und nicht zu einer Newline erweitert.
Gilles 'SO - hör auf böse zu sein'
Dies ist eine gute Antwort, danke. Gibt es einen Link, wo diese Informationen "offiziell" verfügbar sind?
Slashmais
@slashmais Welche Informationen? Die Syntax der Shell-Sprache ist „offiziell“ in verschiedenen Handbüchern und Spezifikationen verfügbar. Von dort aus ist es jedoch nicht ganz einfach, herauszufinden, welche Zeichen wo genau zitiert werden müssen.
Gilles 'SO - hör auf böse zu sein'
1
Ich habe auch folgendes gefunden: tecmint.com/manage-linux-filenames-with-special-characters - es ist nicht so kompakt wie Ihre Liste, hat aber viele Beispiele. (by-the-by: "Welche Informationen?" ist keine coole Antwort, wenn das Thema hier die Charaktere betrifft)
Slashmais