Wie kann ich Klammern schützen, die an einen CD-Befehl übergeben werden?

Wie kann ich Klammern schützen, die an einen CD-Befehl übergeben werden?

Ich fragteHierSo erstellen Sie cdgeschützte Leerzeichen. Die Tab-Vervollständigung ist großartig, aber manchmal fügen Sie den Pfad aus der Zwischenablage ein, sodass dies nützlich ist.

Die Lösung funktioniert jedoch nicht mit Klammern. Egal, wie Sie versuchen, die Eingabe zu umgehen und zu schützen, es wird immer Folgendes zurückgegeben:

bash: syntax error near unexpected token `('

Gibt es eine Möglichkeit, auch Klammern zu berücksichtigen? Ich möchte, dass es funktioniert, wenn ich Folgendes eingebe:

cd My path with spaces (and parentheses)

Antwort1

Um das Argument herum verwenden Sie einfache Anführungszeichen '. (Das funktioniert für jeden Befehl, nicht nur cd).

cd 'My path with spaces (and parentheses)'

Sie können Bash nicht dazu bringen, die Klammern an zu übergeben cd. Um die Leerzeichen überhaupt zum Laufen zu bringen, ist ein sehr spezieller Hack nötig.

Einfache Anführungszeichen gelten für alle Zeichen außer 'sich selbst. Ersetzen Sie einfache Anführungszeichen durch die 4-stellige Zeichenfolge '\''.

cd 'Apostrophe'\''s a pain'

Dies funktioniert nicht, wenn der Verzeichnisname mit einem Bindestrich beginnt, da der cdBefehl das Argument dann als Option interpretiert. --Um dies zu vermeiden, geben Sie es vor dem Verzeichnisnamen ein.

Sehenhttps://unix.stackexchange.com/questions/69144/wie entkomme ich einem Unterverzeichnisnamen mit einem Et-Zeichen darin/69147#69147für mehr Details.

Eine andere Methode besteht darin, dass die Shell eine separate Textzeile liest, anstatt das Argument in der Befehlszeile zu übergeben.

Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$ 

Anstatt manuell zu kopieren und einzufügen, können Sie es auch programmgesteuert tun. Installieren Sie entwederAbonnierenoderxsel.

cd -- "$(xclip -o -selection clipboard)"
cd -- "$(xsel -bo)"

Sie können daraus einen Alias ​​machen.

alias cde='cd -- "$(xsel -bo)"'

Antwort2

So gehen Sie richtig cdauf Verzeichnisse mit Zeichen wie Leerzeichen und Klammern im Namen ein:

Wenn Ihr Ordnername kein einfaches Anführungszeichen enthält ', setzen Sie ihn einfach in einfache Anführungszeichen:

cd 'My path with spaces (and parentheses)'

Wenn es ein enthält ', aber kein Anführungszeichen ", keinen Backlash \, kein Backquote `oder kein Dollarzeichen $, schließen Sie es in doppelte Anführungszeichen ein:

cd "My path with spaces (and parentheses)"

Es kommt nicht sehr häufig vor, dass ein Datei- oder Verzeichnisname sowohl einfache als auch doppelte Anführungszeichen enthält. (Das liegt vielleicht daran, dass es nicht üblich ist, dass ein Datei- oder Verzeichnisname überhaupt doppelte Anführungszeichen enthält. Der einzige Grund, warum ich doppelte Anführungszeichen ursprünglich nicht empfohlen habe, ist, dass doppelte Anführungszeichen im Gegensatz zu einfachen Anführungszeichen die $Erweiterung von Umgebungsvariablen ermöglichen. Das wäre ein Problem, wenn Ihr Dateiname ein $Zeichen gefolgt von Text enthielte.)

Wenn es beides enthält oder Sie einfach eine andere Methode wünschen, können Sie jedes Leerzeichen und jede Klammer manuell maskieren, indem Sie \davor ein Backslash-Zeichen einfügen:

cd My\ path\ with\ spaces\ \(and parentheses\)

Das ist ärgerlich, aber zum Glück ist die Schale mitTU es für dich, wenn Sie den Anfang des Namens eingeben und drücken Tab. Wenn mehrere Datei- oder Verzeichnisnamen mit beginnen My, müssen Sie möglicherweise noch mehr eingeben, damit der Name erweitert wird. Wenn Sie drücken Tabund der Name nicht erweitert wird, können Sie Taberneut drücken, um eine Liste der Dateien anzuzeigen, die mit Ihrer bisherigen Eingabe übereinstimmen. Dann wissen Sie, wie viel Sie noch eingeben müssen, damit der Name eindeutig übereinstimmt und erweitert wird.

Alternativ können Sie die internen Anführungszeichen maskieren. Angenommen, Sie haben einen Ordner mit dem Namen:

Mischa's gardening tips for "home and office"

Sie können verwenden:

cd Mischa\'s\ gardening\ tips\ for\ \"home\ and\ office\"

Sie können aber auch einfach Folgendes verwenden:

cd 'Mischa'\''s gardening tips for "home and office"'

Backslashes sind innerhalb von einfachen Anführungszeichen nichts Besonderes. Daher beenden wir den in einfache Anführungszeichen gesetzten String, hängen ein durch einen Backslash geschütztes einfaches Anführungszeichen an und beginnen sofort einen weiteren in einfache Anführungszeichen gesetzten String, alles ohne Leerzeichen, die ein separates Argument beginnen würden.

Warum Sie die Arbeit wahrscheinlich nicht cdso erledigen können, wie Sie es möchten:

Was cd My path with spaces (and parentheses)die Arbeit angeht: Nein, das können Sie wirklich nicht tun, da dieses Verhalten nicht spezifisch für den cdBefehl ist, sondern Teil der Funktionsweise jedes Befehls ist. Wenn ein Befehl ausgeführt wird, wird eine Liste der vom Benutzer bereitgestellten Argumente ausgegeben. Wenn die Shell ein Leerzeichen sieht, weiß sie, dass ein Argument gerade beendet und ein anderes gerade begonnen hat. Um ein Leerzeichen als Teil eines Arguments zu übergeben, muss es auf eine der oben genannten Arten in Anführungszeichen gesetzt werden.

Sie könnten erreichenTeilvon diesemmancheder Zeit - Sie könnten sich cd My path with spacesArbeit machen, um in den My path with spacesOrdner zu gehen. Sie könnten dies erreichen, indem Sie ein Shell-Skript schreiben, das alle vom Benutzer bereitgestellten Argumente mit Leerzeichen verknüpft. (Wenn Sie möchten, könnten Sie cddieses Skript dann selbst aufrufen lassen, indem Sie einen Shell-Alias ​​erstellen, der cdnach ihm benannt ist; das hätte Vorrang vor dem Shell-Builtin, cddas Sie derzeit normalerweise ausführen.) Aber:

  • Das Skript würde keine unterschiedlichen Argumente für My path with spacesund erhalten My path with spacesund würde daher cd My path with spacesfehlschlagen oder den falschen Ordner eingeben.

  • Für die Klammern ist dies nicht möglich, da diese von der Shell zur Gruppierung verwendet werden und daher in keiner Weise an einen Befehl weitergegeben werden. Tatsächlich wird die Shell in den meisten Fällen einfach einen Syntaxfehler ausgeben (wie Sie gesehen haben):

    ek@Kip:~$ cd My path with spaces (and parentheses)
    bash: syntax error near unexpected token `('
    

    Unabhängig davon, was Sie ändern, tritt dieser Syntaxfehler weiterhin auf, wenn dieser Befehl eingegeben wird.

Ich sage, dass Sie das „wahrscheinlich“ nicht hinbekommen, weil es einen Weg gibt, der funktioniert: Sie können Ihre eigene Shell erstellen, die sich so verhält, wie Sie es wünschen. Aber das ist extrem schwierig und es ist unwahrscheinlich, dass irgendjemand das tun würde, nur um diese Änderung vorzunehmen. (Sie könnten auch den Quellcode einer vorhandenen Shell ändern, was eine praktischere Lösung ist, aber immer noch mehr Aufwand erfordert, als die meisten Leute aufbringen möchten.) Außerdem ist es unwahrscheinlich, dass es cdVerzeichnisnamen mit beliebigen Zeichen, einschließlich Leerzeichen, akzeptieren kann, wie es unter Windows der Fall ist.

Falls Sie sich fragen, warum dies unter Windows funktioniert, unter Ubuntu jedoch nicht: Unter Windows wird Befehlen der nach ihnen eingegebene Text alsTextzeichenfolge, und wenn ein Befehl diese Zeichenfolge als Folge separater Argumente interpretieren muss (was normalerweise, aber nicht immer der Fall ist), muss der Code für den Befehl eine spezielle Bibliotheksfunktion aufrufen, die die Befehlszeilenzeichenfolge analysiert. (In einem C-Programm geschieht dies im Hintergrund, erfordert aber dennoch die Verwendung der Windows-API.)

verwandte Informationen