Das folgende Skript gibt mir manchmal Dinge wiecan't remove a/b as it's not empty
ssh -T user@host <<EOF
cd somewhere
rm -rf a/b
EOF
Aber ich melde mich beim Server an und führe aus, rm -rf a/b
dann hatte ich nie das Problem.
Es gibt andere Prozesse, für die Dateien generiert werden. Ist a/b
das verwandt?
Wie kann man ein Skript erstellen, das sicherstellt, dass "a / b" gelöscht wird?
rm -rf
sollte immer gelingen, ohne Erlaubnisprobleme. Bitten Sie das Skript, die Debugging-Ausgabe zu drucken, wenn das Entfernen fehlschlägt.ls -laR a/b
sollte ausreichen.Antworten:
rmdir(2)
schlägt fehl, wenn das Verzeichnis nicht leer ist. Wenn ein anderer Prozess Dateien erstellt, währendrm(1)
er sie entfernt, weiß er nicht, ob er sie löschen soll. Wenn es daher an der Zeit ist,rm(1)
zu versuchen, das zu löschen, was seiner Meinung nach ein leeres Verzeichnis sein sollte, schlägt dies mit dem von Ihnen veröffentlichten Fehler fehl.Eine Möglichkeit, das Verzeichnis angesichts gleichzeitiger Dateierstellungen im Verzeichnis zu löschen, besteht darin, es umzubenennen:
Es ist möglich, dass dies nicht funktioniert, wenn die Prozesse, in denen die Dateien erstellt
a/b
werden, dies nicht nach Pfad (open(2)
vs.openat(2)
) tun .Ich gehe davon aus, dass die Prozesse, in denen Dateien erstellt
a/b
werden, dieses Verzeichnis neu erstellen, wenn es nicht vorhanden ist, oder Fehler ordnungsgemäß behandeln, wenn es nicht vorhanden ist. Da Sie bereits versuchen, das Verzeichnis unter anderen Prozessen zu löschen, scheint dies eine sichere Annahme zu sein.quelle
Sehr wahrscheinlich. Möglicherweise werden
rm -rf
zuerst alle Dateien und dann alle Verzeichnisse entfernt. Unter der Haube schlägt derrmdir
Systemaufruf zum Entfernen eines Verzeichnisses fehl, wenn das Verzeichnis nicht leer ist. Möglicherweise läuft eine Race-Bedingung, bei derrm -rf
überprüft wird, ob das Verzeichnis leer ist und ob es leer ist. Ein anderer Prozess erstellt dann eine neue Datei.rm -rf
ruft schließlich aufrmdir
, aber ein anderer Prozess erstellt vorher eine Datei.Faheems Rat ist gut: Setzen Sie einen
ls
in Ihren Fehlerzustandquelle
&&
sollte;
oderls
wird das Beenden des Skripts verhindern.ls
zeigt an, dass sich in diesem Verzeichnis neue Dateien befinden. Ich werde diemv
Lösung ausprobieren.ls
fehlschlägt, gibt die Subshell den Fehlercode zurückls
. Das '&& exit 1
' ist erforderlich, um sicherzustellen, dass die Sub-Shell beils
Erfolg weiterhin einen Fehlercode zurückgibt. Wenn Sie '||' ersetzen, maskieren Sie den wahren Fehlercode fürls
.Bei sehr hohen Race-Bedingungen: Der nächste Befehl entfernt veraltete Dateien und dann leere Verzeichnisse:
Oder Schritt für Schritt:
Schlaf 30 ist für alle Prozesse erforderlich, um das Schreiben in das Entfernungsverzeichnis zu beenden.
WARNUNG: Sie können Ihre neuen Daten verlieren (in meinem Fall handelt es sich um einen Cache, es ist mir also egal).
quelle