Wie kann man eine Datei mit dem Namen "-" "verkleinern"?

17

Ich habe versehentlich eine Datei mit dem Namen -(zB seq 10 > -) erstellt. Dann habe ich versucht, lesses anzuzeigen, aber es hängt nur.

Ich verstehe, dass dies geschieht, weil less -Eingaben von erwartet werden stdin, so dass es nicht -als Dateiname interpretiert wird . Ich habe es versucht, less \-aber es funktioniert auch nicht.

Gibt es eine Möglichkeit, anzuzeigen, lessdass -es sich um eine Datei und nicht um stdin handelt?

Das Beste, was ich bekommen konnte, ist:

find -name '-' -exec less {} +
fedorqui
quelle
2
@muru danke für den Kommentar, aber das mögliche Duplikat ist so spezifisch, dass ich nicht denke, dass es als "genaues Duplikat" qualifiziert ist. Wenn es umformuliert wurde zu etwas allgemeinerem wie "wie man auf eine Datei zugreift, die mit '-' beginnt", vielleicht.
Fedorqui
4
Das ist keine doppelte Frage. Der Fall für sich -ist anders. -ist keine Option.
Stéphane Chazelas
1
@terdon Ich glaube nicht, dass die gleiche Antwort direkt bedeutet, dass es sich um Duplikate handelt. Irgendwo in Meta SO gab es ein Beispiel: Wenn eine Frage mit "Nein" beantwortet wird, wäre alles, dessen richtige Antwort "Nein" ist, ein Duplikat? Wie ich bereits sagte, wäre es interessant, den Kandidaten für das Duplikat so umzuformulieren, dass er allgemeiner ist. ansonsten macht es wenig sinn, dort andere fragen wie diese zu stellen.
Fedorqui
4
@terdon, nein. Die dort akzeptierte Lösung wird hier nicht funktionieren. Und nein, -wird nicht als Option behandelt, das ist ein völlig anderes Problem als bei Argumenten, die zufällig wie Optionen geformt sind.
Stéphane Chazelas
2
Es ist nicht erforderlich, -einzelne Anführungszeichen in Anführungszeichen '-'oder Escapezeichen zu setzen, \-da dies -kein Sonderzeichen für allgemeine Shells ist (zumindest POSIX-konforme). Das Ergebnis ist das gleiche.
Pabouk

Antworten:

53

Stellen Sie einfach Folgendes voran ./:

less ./-

Oder verwenden Sie die Umleitung:

less < -

Beachten Sie, dass, da -(im Gegensatz zu -xoder --foo--zum Beispiel) ein spezieller Dateiname anstelle einer Option betrachtet wird, Folgendes nicht funktioniert:

less -- -   # THIS DOES NOT WORK
Howard
quelle
3
Übrigens, das find -name '-' -exec less {} +läuft.
Stéphane Chazelas
6
@fedorqui, nein, es ist nur so, -und ./-(oder /path/to/-oder ../to/-) sind zwei (4) gültige Pfade zu dieser -Datei, aber ein -Argument ist speziell für less(bedeutet, aus stdin lesen), während ./-es nicht speziell ist.
Stéphane Chazelas
2
@fedorqui find -name '-' -exec less {} +ist das nicht standardisierte Formular für find . -name '-' -exec less {} +. Es steigt den Baum bei ab .und findet Dateien und übergibt die Pfade dieser Dateien als Argumente an less. Ersetzen Sie -exec lessdurch, um -exec echo lesszu sehen, was gerade ausgeführt wird.
Stéphane Chazelas
4
@ Haylem, --ist das Ende der Optionen zu markieren. Hier hilft es nicht. Dies -ist keine Option, sondern ein spezielles Argument, das keine Option ist. Siehe auch unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
3
@ Haylem, versuch es selbst. --wird von getopt () behandelt, um das Ende von Optionen zu markieren, wird von getopt () -nicht als Option erkannt, so dass -als normales Argument erkannt wird, ob angegeben --oder nicht. Und als normales Argument wird es, lesswie die meisten Textdienstprogramme, als stdin behandelt, was wir hier nicht wollen.
Stéphane Chazelas
3

Ich würde es einfach tun mv - f && less f. Problem gelöst.

snth
quelle
Nun, das funktioniert, obwohl es mich an die NASA erinnert, die Millionen ausgegeben hat, um einen Stift zu entwickeln, der im Weltraum schreiben würde, während die sowjetischen Kosmonauten einen Bleistift verwendeten . Ich denke, wir können es uns leisten, hier ein wenig in Forschung zu investieren.
Fedorqui
+1 Warum komplizieren Dinge, wenn es eine einfache Lösung gibt.
Mhmd
3

Hinweis: Meine Antwort ist im Fall des OP NICHT gültig und gilt nur für Werkzeuge, die der unten genannten Konvention folgen, und nicht für eine Datei mit dem Namen genau nur -(Bindestrich). Dies ist häufig auch ein Sonderfall, um diese Ablesung aus dem Standard anzugeben Eingabe wird erwartet. Siehe die akzeptierte Antwort.

Lassen Sie dies hier, da es nützliche Informationen für andere Fälle enthält, auf die man bei der Suche nach Antworten stoßen kann.


Double-Dash es!

Verwenden Sie die Standardkonvention double-dash ( --), um das letzte Argument anzugeben:

less -- -FILENAME

Beispiel

$ echo "meh" > -badname
$ less -badname
Number is required after -b
$ less -- -badname # GREAT SUCCESS!

Was ist los?

Dieses --Argument stammt aus einer Konvention, die von den meisten Implementierungen von Shell-Dienstprogrammen und Befehlszeilentools unterstützt wird, und die meisten Shells werden sichtbar dafür plädieren, dass Sie beim Implementieren von CLI-Tools die Konvention befolgen sollten.

Empfohlen von der Open Group

Die OpenGroup erwähnt es auch im Abschnitt Utility description defaults (v6) ihrer Basisspezifikation:

Standardverhalten: [...] Standarddienstprogramme, die keine Optionen akzeptieren, aber Operanden akzeptieren, erkennen "-" als erstes zu verwerfendes Argument.

Die Anforderung zum Erkennen von "-" besteht darin, dass konforme Anwendungen eine Möglichkeit benötigen, ihre Operanden vor beliebigen Optionen zu schützen, die die Implementierung als Erweiterung bereitstellen kann. Wenn für das Standarddienstprogramm foo beispielsweise angegeben ist, dass es keine Optionen verwendet, und die Anwendung einen Pfadnamen mit einem führenden Bindestrich benötigt, kann dies sicher folgendermaßen erfolgen:

foo -- -myfile

und vermeiden Sie Probleme mit -m als Erweiterung.

Und in den Utility-Syntaxrichtlinien (v7):

Leitlinie 10: Das erste Argument, das kein Optionsargument ist, sollte als Trennzeichen für das Ende von Optionen akzeptiert werden. Alle folgenden Argumente sollten als Operanden behandelt werden, auch wenn sie mit dem Zeichen "-" beginnen.

Empfohlen von Bash

Hier ein Auszug aus dem Bash-Handbuch über die eingebauten Funktionen, die es unterstützen:

Sofern nicht anders angegeben, wird bei jedem in diesem Abschnitt dokumentierten eingebauten Befehl das Akzeptieren von Optionen vorangestellt und - acceptiert -, um das Ende der Optionen zu kennzeichnen.

Die eingebauten Funktionen:, true, false und test akzeptieren keine Optionen und werden nicht speziell behandelt. Die eingebauten Funktionen exit, logout, break, continue, let und shift akzeptieren und verarbeiten Argumente beginnend mit - ohne dass dies erforderlich ist -. Andere integrierte Funktionen, die Argumente akzeptieren, aber nicht als akzeptierende Optionen angegeben sind, interpretieren Argumente, die mit ungültigen und erforderlichen Optionen beginnen, um diese Interpretation zu verhindern.

Beachten Sie, dass das Echo nicht interpretiert - um das Ende der Optionen zu bedeuten.

Zusätzliche Lektüre

Haylem
quelle
2
+1: Die portabelste und
befehlsunabhängigste
2
@Kwaio einen Hinweis auf die "Best Practice"? Sei einfach neugierig.
Fedorqui
24
Diese Antwort gilt für Argumente, die wie Optionen aussehen. Es ist nicht der Fall, für -den es keine Option gibt. Verwenden ./-oder Umleiten, wenn möglich, ist im Allgemeinen ein besserer Ansatz, da andere Arten von Problemen wie das foo=barvon awkoder das vermieden werden -. Siehe auch unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
7
Wie Stéphane sagt, beantwortet dies die Frage nicht. less -- -werde immer noch versuchen von stdin zu lesen.
Michał Politowski
5
Möglicherweise möchten Sie die Antwort löschen (oder in die andere Frage verschieben, da hier nützliche Verweise enthalten sind) oder klarstellen, dass sie für diesen speziellen Fall nicht gilt (und möglicherweise erläutern, warum was noch nützlicher wäre).
Stéphane Chazelas