Bash: In Datei umleiten, immer neu erstellen

8

In Bash eine Befehlsverknüpfung

echo test > actual.txt

ersetzt den Inhalt der aufgerufenen Datei actual.txtdurch "test" und erstellt die Datei, falls sie nicht vorhanden ist. Wenn die Datei jedoch vorhanden ist, öffnet bash sie einfach, schneidet sie ab und schreibt den neuen Inhalt in die Datei.

Insbesondere schlägt der Umleitungsbefehl in diesem Szenario fehl:

ln -s /some/illegal/path link.txt
echo test > link.txt

Bash 4.4.12 gibt mir die verwirrende Fehlermeldung link.txt: No such file or directory.

Eine Möglichkeit, dies zu vermeiden, besteht darin, die Datei zu löschen, bevor Sie den umgeleiteten Befehl ausführen.

rm link.txt && echo test > link.txt

Ich habe mich jedoch gefragt, ob es einige Optimierungen der Bash-Optionen oder des Umleitungsoperators gibt, die diesen Fehlermodus verhindern. Irgendwelche Ideen?

itsadok
quelle
Was passiert , wenn link.txtein Link zu /dir/filedem /direine Datei des Typs Verzeichnis , in dem Sie schreiben haben und die Erlaubnis suchen, aber /dir/filenicht existiert (und die Umleitung wäre es ohne eine Fehlermeldung erstellen)? Was ist, wenn /dir/filees eine reguläre Datei gibt (Gerät, FIFO, Verzeichnis ...) oder Sie keine Schreib- oder Suchberechtigung dafür haben /dir?
Stéphane Chazelas

Antworten:

7

Der Versuch, in einen toten symbolischen Link zu schreiben, entspricht dem Versuch, in einen Pfad zu schreiben, der nicht existiert. Es gibt keine Möglichkeit, die Ausgabeumleitung zu "optimieren", um den Pfad (einschließlich Zwischenverzeichnisse) zu erstellen bash, und es gibt keine Shell-Optionen bash, die dies automatisch machen.

Wenn der Zwischenpfad vorhanden ist, der Endpunkt der Verknüpfung jedoch nicht, wird er durch die Umleitung erstellt.

Sie können so etwas tun

if [ -h file ] && [ ! -f file ]; then
    rm file
fi

um zu testen, ob "Datei" ein symbolischer Link ist ( -h) und ob er sich auf eine reguläre Datei bezieht, die existiert ( -f). Wenn es sich um einen symbolischen Link handelt, der sich jedoch nicht auf eine Datei bezieht, löschen Sie ihn.

Kusalananda
quelle
1
Der Punkt meiner Frage war, dass ich nicht versuche, an irgendetwas zu schreiben . Ich möchte eine neue Datei mit dem Namen erstellen link.txt, und an derselben Stelle befindet sich zufällig ein symbolischer Link. Um dies in Form einer Frage zu formulieren: Warum sollte ich mich mit dem Testen beschäftigen, wenn ich die Datei in der nächsten Zeile überschreiben werde? Ich kann es einfach tun rm -fund es wird den gleichen Effekt haben.
Itsadok
3
@itsadok Ah. Ja. Nur rm -f filenamevor dem Schreiben mit der Umleitung zu tun, würde auch Ihr Problem lösen. Es hängt aber auch davon ab, ob Sie möchten, dass es sich im aktuellen Verzeichnis oder in dem Verzeichnis befindet, in dem sich der Endpunkt des symbolischen Links befindet.
Kusalananda
Möglicherweise fehlen Ihnen noch die Berechtigungen für rmdie Datei oder zum Schreiben. Wie in vielen Fällen können Sie sich nicht auf alles vorbereiten. Sie müssen beurteilen, welche Fälle Sie wirklich erwarten (wenn auch nur in seltenen Fällen) und daher behandeln, welche Fälle Sie für so unwahrscheinlich halten, dass Sie sie absichtlich nicht behandeln, und akzeptieren, dass es eine bestimmte Anzahl von Fällen gibt, die Sie nicht berücksichtigen und kann also nicht damit umgehen.
Alfe