[GELÖST] Datei mit Vorzeichen lässt sich nicht löschen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
JamesByrnes
Beiträge: 106
Registriert: 24.11.2021 11:11:04

[GELÖST] Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von JamesByrnes » 13.09.2022 08:47:41

Hi,

ich habe eine Datei, die heißt "-i". Die lässt nicht öffnen oder löschen:

Code: Alles auswählen

cat '-i'
cat: Ungültige Option -- i
„cat --help“ liefert weitere Informationen.

cat -i
cat: Ungültige Option -- i
„cat --help“ liefert weitere Informationen.
usw.
Wie lässt sich diese Datei beseitigen? Weder Hochkomata, noch Anführungszeichen oder Akzentzeichen helfen.

Vielen Dank
James Byrnes
Zuletzt geändert von JamesByrnes am 13.09.2022 09:16:11, insgesamt 1-mal geändert.

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von JTH » 13.09.2022 09:02:28

Code: Alles auswählen

rm "\-i"
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von Meillo » 13.09.2022 09:04:35

Das liegt daran, dass der Dateiname, durch das Minuszeichen, als Kommandozeilenargumente angesehen wird.

Verwende stattdessen eine alternative Pfadangabe zu der Datei. Im einfachsten Fall einen relativen Pfad zum aktuellen Verzeichnis:

Code: Alles auswählen

rm ./-i
Alternativ kannst du mit `--' die Optionen von Dateinamen trennen:

Code: Alles auswählen

rm -- -i
Alles hinter `--' wird als Dateinamen behandelt, selbst wenn es wie eine Option aussieht.
Use ed once in a while!

JamesByrnes
Beiträge: 106
Registriert: 24.11.2021 11:11:04

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von JamesByrnes » 13.09.2022 09:06:40

JTH hat geschrieben: ↑ zum Beitrag ↑
13.09.2022 09:02:28

Code: Alles auswählen

rm "\-i"
Danke für das Feedback, aber die Maskierung funktioniert leider auch nicht. Mit keiner der oben genannten Möglichkeiten.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von Meillo » 13.09.2022 09:11:10

Zum technischen Verstaendnis:

Mit dem Shell-Escaping hat das hier nichts zu tun. Escaping ist dafuer da, festzulegen, was als ein Wort gilt und welche Zeichen die Shell nicht interpretieren soll.

Optionen werden aber nicht von der Shell sondern von den Tools selber interpretiert. Darum funktioniert `--' auch nur bei GNU-Tools und nicht generell bei allen Tools.

Ebenso: bei alten Unix-Tools werden Optionen hinter Dateinamensargumenten nicht mehr als Optionen angesehen. Mit einem alten `rm' haettest du das Problem auch so loesen koennen:

Code: Alles auswählen

touch a
rm a -i
Bei den GNU-Tools geht das aber nicht, da diese Optionen ueberall auf der Kommandozeile erkennen.
Use ed once in a while!

Benutzeravatar
cosinus
Beiträge: 3422
Registriert: 08.02.2016 13:44:11
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Bremen

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von cosinus » 13.09.2022 09:11:27

Geht denn das :?:

Code: Alles auswählen

rm '-i'

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von Meillo » 13.09.2022 09:12:17

cosinus hat geschrieben: ↑ zum Beitrag ↑
13.09.2022 09:11:27
Geht denn das :?:

Code: Alles auswählen

rm '-i'
Nein. Siehe meine Erklaerung zum technischen Hintergrund.


Die Loesung ist:

Code: Alles auswählen

rm ./-i
Use ed once in a while!

JamesByrnes
Beiträge: 106
Registriert: 24.11.2021 11:11:04

Re: Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von JamesByrnes » 13.09.2022 09:15:53

Meillo hat geschrieben: ↑ zum Beitrag ↑
13.09.2022 09:12:17
Die Loesung ist:

Code: Alles auswählen

rm ./-i
Vielen Dank für die Erklärung! Dieser Weg hat auf jeden Fall geklappt.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [GELÖST] Datei mit Vorzeichen lässt sich nicht löschen

Beitrag von Meillo » 13.09.2022 09:39:43

Vielleicht erklaere ich nochmal etwas genauer wie das hier technisch funktioniert.

Die Shell liest die Eingabezeile, fuehrt ein paar Ersetzungen/Expansions durch, teilt die fertig bearbeitete Zeile dann in Woerter auf und ruft dann den Befehl im ersten Wort mit allen weiteren Woertern als Argumenten auf.

Bei der Eingabezeile

Code: Alles auswählen

foo bar baz
muss die Shell keine Ersetzungen machen. Sie teilt die Zeile in drei Worte:

Code: Alles auswählen

foo
bar
baz
und ruft dann den Befehl `foo' mit den Argumenten `bar' und `baz' auf.

Nun zum Escaping. Bei der Eingabezeile

Code: Alles auswählen

foo "bar baz"
muss die Shell wieder keine Ersetzungen machen. Sie teilt die Zeile diesmal, wegen der Quotes, in *zwei* Woerter auf:

Code: Alles auswählen

foo
bar baz
und ruft dann den Befehl `foo' mit dem einen Argument `bar baz' auf.

Nun zur Variablenexpansion. Nehmen wir an, die Variable `a' hat den Wert `b c'. Bei der Eingabezeile

Code: Alles auswählen

foo $a blubb
macht die Shell zuerst eine Variablenexpansion und ersetzt `$a' durch den Wert `b c'. Damit lautet die Eingabezeile nun

Code: Alles auswählen

foo b c blubb
Nun teilt die Shell das in vier Worte auf:

Code: Alles auswählen

foo
b
c
blubb
Anschliessend ruft sie den Befehl `foo' mit den drei Argumenten `b', `c' und `blubb' auf.

Nun Expansion mit Escaping/Quoting. Wenn die Variablenexpansion gequotet ist und die Eingabezeile so lautet

Code: Alles auswählen

foo "$a" blubb
dann kommt wieder zuerst die Ersetzung was die Befehlszeile so veraendert:

Code: Alles auswählen

foo "b c" blubb
Dann macht die Shell daraus, wegen der Quotes, nur drei Woerter:

Code: Alles auswählen

foo
b c
blubb
Und ruft dann `foo' mit den zwei Argumenten auf.

Nun noch Singlequotes. Bei der Eingabezeile

Code: Alles auswählen

foo '$a' blubb
macht die Shell keine Variablenexpansion, da sie durch die Singlequotes das Dollarzeichen nicht als Sonderzeichen ansieht, sondern literal verwendet. Die Shell teilt also in drei Worte auf:

Code: Alles auswählen

foo
$a
blubb
und ruft anschliessend den Befehl `foo' mit den zwei Argumenten `$a' und `blubb' auf.

Ihr koennt all diese Faelle durchspielen wenn ihr statt dem Befehl `foo' den Befehl `echo' verwendet, oder noch anschaulicher mit folgender Shellfunktion:

Code: Alles auswählen

foo() { echo "args: $#"; for i in "$@"; do echo "arg: '$i'"; done; }


Nun zu dem Fall mit dem `-i':

Die Befehlszeile ist also

Code: Alles auswählen

rm -i
Die Shell muss keine Expansionen machen. Sie teilt in zwei Woerter:

Code: Alles auswählen

rm
-i
Dann ruft sie den Befehl `rm' mit dem Argument `-i' auf. -- Der Shell ist voellig egal was in den Argumenten steht. Sie interessiert sich nur fuer Expansionen (fuer die das Minuszeichen keine Bedeutung hat) und fuer Worttrennung (wofuer es auch keine Bedeutung hat).

Ebenso im Fall der Eingabezeile

Code: Alles auswählen

rm '-i'
Hier laeuft es exakt identisch ab wie im vorigen Fall, da Singlequotes nur dann einen Unterschied machen, wenn in ihnen Sonderzeichen der Shell oder Whitespace steht -- beides ist hier nicht der Fall. Fuer die Shell ist ein ebenso normales Wort wie

Code: Alles auswählen

hallo
Beides besteht aus lauter fuer sie uninteressanten Zeichen.

Aus diesem Grund ist es voellig egal wie man `-i' quotet -- das Minus hat fuer die Shell selbst ueberhaupt keine Bedeutung.



Das Minus hat nur fuer Befehle eine Bedeutung, bei denen damit Kommandozeilenoptionen eingeleitet werden. Das ist erst nachdem die Shell fork() und exec() aufgerufen hat und damit die Kontrolle an das aufgerufene Programm uebergeben hat.

Die Loesung liegt also nicht darin, irgendetwas fuer die Shell zu machen (Stichwort: Escaping/Quoting), sondern darin, etwas dagegen zu machen, dass das aufgerufene Programm (hier `rm') das Argument als Option ansieht. Das verhindert man indem man dafuer sorgt, dass das Minuszeichen nicht das erste Zeichen im Argument ist ... indem man eine andere Pfadangabe zur gleichen Datei nutzt.


Ich hoffe, mit dieser Erklaerung ist etwas mehr Verstaendnis und Klarheit in diesen Bereich gekommen. Wenn gewuenscht, kann ich gerne einzelne Aspekte nochmal genauer erklaeren.
Use ed once in a while!

Antworten