rm -rf nie usuwa zawartości folderu, ale tworzy kolejny pusty


0

Obecnie piszę skrypt startowy dla serwera gry Minecraft. W tym skrypcie załączyłem skrypt zapasowy.

Ten skrypt kopii zapasowej działa prawie idealnie, ale zamiast usuwać zawartość folderów, tworzy tylko kolejny (podobnie nazwany) i nie robi nic z docelowym folderem.

Używam tego polecenia: rm -rf "$MINECRAFT_PATH/server.log backups/*"
To polecenie jest wykonywane w skrypcie bash.

Zmienna $MINECRAFT_PATHzawiera poprawną ścieżkę. Utworzony folder ma następującą nazwę: server.log.backups(Zwróć uwagę na kropkę pomiędzy logi backups). Ale ukierunkowane folder ma tę nazwę: server.log backups. Ten folder istnieje i nie stanowi to problemu.


3
rmnie można utworzyć katalogu. Podwójne cudzysłowy zapobiegają ekspansji symboli wieloznacznych.
choroba

Ale jakoś powstało! Nadal tego nie rozumiem!
BrainStone

Prawdopodobnie został stworzony wcześniej w skrypcie.
choroba

Dziwne jest to, że teraz folder nie jest tworzony! (Zmieniłem skrypt zgodnie z rozwiązaniem).
BrainStone

Odpowiedzi:


2

Podwójne cudzysłowy w Bash zachowują większość dosłownych wartości treści, więc *glob jest przekazywany dosłownie do rm, który spróbuje usunąć plik lub folder o nazwie *. $MINECRAFT_PATHPodstawiony chociaż.

Prawdopodobnie chcesz:

rm -rf "$MINECRAFT_PATH/server.log backups/"*

Spowoduje to usunięcie zawartości server.log backupsfolderu.

Niektóre alternatywy:

  • Możesz zaprogramować skrypt bardziej defensywnie, usuwając w ten sposób -fopcję rm. W takim przypadku nie powiedzie się, jeśli server.log backupsfolder będzie pusty, ponieważ glob nie zostanie rozwinięty i przekazany dosłownie, a plik nie zostanie wywołany server.log backups/*.

  • Możesz po prostu rm -rfcały folder i mkdir -ppóźniej.

  • Lub możesz po prostu zrobić głębokie usunięcie wszystkich plików i folderów w server.log backupsfolderze. -mindepth 1zapobiega usunięciu rodzica:

    find "$MINECRAFT_PATH/server.log backups" -mindepth 1 -depth -delete

Sam folder też został usunięty!
BrainStone

Nie mogę śledzić, jeśli folder jest pusty, *należy przekazać go bezpośrednio do polecenia: mkdir foo; echo foo/*zwraca foo/*. Więc rm foo/*powinien spróbować usunąć plik *wewnątrz foo, co nie istnieje, ale nie zwraca błędu ani powodu -f. Ale folder foo/nie powinien zostać usunięty. (Przynajmniej domyślnie bash 4na moim debianie, czy jest inaczej w OSX?)
mpy

@mpy Masz rację, że tak się nie powinno stać. Myliłem się tutaj. Jednak zależy to również od powłoki, jaki dokładnie błąd zostanie zgłoszony. Najlepiej byłoby, gdyby skrypt został zaprogramowany w sposób defensywny bez użycia -fopcji rmsprawdzania, czy coś pójdzie nie tak.
slhck,

@BrainStone Czy możesz sprawdzić aktualizację mojej odpowiedzi?
slhck,

Sprawdziłem to dwukrotnie. I wygląda na to, że zapomniałem *. Teraz działa. Dziękujemy również za rozszerzoną odpowiedź!
BrainStone
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.