Zastąpić istniejący katalog?

11

Mam nazwę katalogu foow ~/Desktop. Załóżmy, że chcę utworzyć katalog z terminala o tej samej nazwie i w tej samej lokalizacji. Kiedy próbowałem mkdir, wystąpił błąd:

mkdir: cannot create directory `/home/nux/Desktop/foo': File exists

To ma sens, ale chcę je wymienić, foojeśli istnieje. Przejrzałem, man mkdirale nie ma takiej możliwości.

Jak więc zastąpić fookatalog?

Dlaczego nie mkdirma takiej możliwości?

nux
źródło
Zastąpić foojak usunąć całą zawartość? mkdirma -popcję, która ignoruje, jeśli katalog istnieje.
muru
4
Czy chcesz komendy, która usunie wszystkie pliki w katalogu, gdy przypadkowo utworzysz nowy katalog o tej samej nazwie? Zastanawiasz się, dlaczego nie ma takiej opcji? Czy to żart?
Marty Fried
downvoters wyjaśniają tylko dlaczego, pytam o jedno polecenie, które usuwa istniejący katalog
nux
1
@nux dla mnie pytanie nie ma sensu ... wyjaśnij, dlaczego kiedykolwiek chcesz usunąć i ponownie utworzyć katalog. Mamy polecenia do wszystkiego, co musisz zrobić w katalogu. mkdir nie potrzebuje opcji usuwania / ponownego tworzenia.
Rinzwind
1
czy to przestępstwo, jeśli zadam logiczne pytanie !!
nux

Odpowiedzi:

21

Jeśli Twoim celem jest wykonanie polecenia jednowierszowego, które:

  • Usuwa i odtwarza katalog, ~/Desktop/foojeśli już istnieje.
  • Po prostu tworzy katalog, ~/Desktop/foojeśli jeszcze nie istnieje.

Następnie możesz użyć:

rm -r ~/Desktop/foo; mkdir ~/Desktop/foo

; jest równoważny nowej linii, ale umożliwia wykonywanie wielu poleceń w jednym wierszu (tj. jako „pojedyncze polecenie”).

  • Jeśli usuwany katalog może zawierać tylko do odczytu pliki, będziesz potrzebować -fflagi, aby je usunąć bez monitowania użytkownika interaktywnie. Jest w porządku, ale zalecam zachowanie szczególnej ostrożności rm -rf .... Zobacz man rmszczegóły.
  • Potrzebujesz rmpolecenia, aby zakończyć, zanim mkdirpolecenie zostanie wykonane; to jest powód, aby użyć ;zamiast &. (Polecenie poprzedzające &działa asynchronicznie w tle).
  • Potrzebujesz mkdirkomendy do uruchomienia, gdy rmkomenda się powiedzie; to jest powód, aby użyć ;zamiast ||.
  • Musisz uruchomić mkdirpolecenie, gdy rmpolecenie się nie powiedzie (zwykle błąd oznacza, że ​​katalog jeszcze nie istniał); to jest powód, aby użyć ;zamiast &&.
  • rmPolecenie może zawieść nawet gdy katalog już istnieje, w którym to przypadku mkdirkomenda nie powiedzie się również, ale komunikaty o błędach będzie sensu i nie ma chyba potrzeby dodawać środkowy sprawdzanie krok do foo„s istnienia przed próbuje go utworzyć.

Zobacz 3.2.3 listy poleceń w podręczniku Reference Bash więcej informacji i wyjaśnień na temat ;, &, ||oraz &&operatorów.

Zgodnie z sugestią Muru (i rozwiniętą przez Rinzwind ), polecamrsync sprawdzić, czy spełni twoje potrzeby tworzenia kopii zapasowych. Na stronie dokumentacji rsync znajduje się kilka dodatkowych przydatnych przewodników , a także ten przewodnik Ubuntu rsync .

dlaczego mkdir nie ma tej opcji?

mkdirtworzy katalogi („mk” oznacza „make” ). Gdyby również rekurencyjnie usuwać katalogi i wszystkie pliki w nich byłyby złe, ponieważ naruszałoby to zasadę najmniejszego zdziwienia w sposób, który prawdopodobnie prowadziłby do utraty danych.

rmdirnawet nie usuwa katalogów, które zawierają pliki (inne niż katalog). rmma -ropcję, która ma sens, ponieważ rmoczekuje się, że usunie pliki (to jest jej cel, dlatego nieodłączne niebezpieczeństwo jest intuicyjne, a użytkownicy zwykle wiedzą, że należy zachować ostrożność podczas uruchamiania rmpoleceń).

Eliah Kagan
źródło
+1 doskonała. Ta odpowiedź wykracza poza wyjaśnianie składni. Chciałbym, aby w witrynach stackexchange było coś głębszego. W tej odpowiedzi jest wiele złotych samorodków.
Govind Rai
7

Nie, nie ma jednego polecenia, aby wykonać to, o co prosisz.

Dlaczego?

Oto filozofia Uniksa: pisz programy, które robią jedną rzecz i robią to dobrze. Pisz programy do współpracy. 1

W tym przypadku polecenia mkdiri rmwykonują to, czego potrzebujesz, i działają dobrze razem, ponieważ rm -rspowoduje również usunięcie katalogu, a następnie mkdirutworzenie katalogu.

1 The Art of Unix Programming , Eric S. Raymond, sam cytując Douga McIlroya.

muru
źródło
na razie to dobra odpowiedź, będę jej szukał
oprócz
3

Polecenie usunięcia katalogu to rm. Potrzebujesz więc 2 poleceń.

rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/

Jak pokazano w komentarzach, możesz połączyć je za pomocą ;(= wykonaj oba, nawet jeśli 1. nie powiedzie się) lub &&(= tylko mkdir, gdy rm nie zawiedzie).

-rJest do usuwania katalogów. Pierwsze polecenie usuwa również CAŁĄ zawartość katalogu. Jeśli NIE jest to twoja intencja, zarówno rm, jak i mkdir nie są tym, czego szukasz: uprawnienia to chmodi chown.

dlaczego mkdir nie ma tej opcji?

Dwuznaczność. mkdiroznacza zrobić katalog. Nie usuwaj i nie twórz katalogu. A ponieważ rmpolecenie służy do usuwania rzeczy, nie ma potrzeby rmdirusuwania katalogu.

Rinzwind
źródło
wiem o tym, ale mam na myśli jedno polecenie, możesz zobaczyć moją edycję, zmieniam ją
nux
1. wyjaśnij, dlaczego musisz ponownie utworzyć katalog. To nie ma dla mnie sensu.
Rinzwind
czy moja potrzeba ma sens, po prostu zastanawiam się jak? ma to dla mnie sens :)
nux
@nux nie to nie. I opiekun mkdir też nie rozumie, dlaczego;) To, czego chcesz, jest bezużyteczne i nie ma żadnych zalet.
Rinzwind
ok, jeśli chcesz wiedzieć, że tworzę skrypt do tworzenia kopii zapasowej w nowym katalogu o tej samej nazwie foo i pozwala go zastąpić, jeśli istnieje, aby zmniejszyć ilość miejsca
nux
1

Aby to zrobić w najczystszy sposób, używam tego:

create_clean_directory(){
    dir_name=$1
    if [ -d "$dir_name" ]; then
        echo "Removing $dir_name"
        rm -rf "$dir_name"
    elif [ -f "$dir_name" ]; then
        echo "File with this name already exists, not a directory."
        exit
    fi
    if mkdir "$dir_name"; then
        echo "Clean directory created: $dir_name"
        return 0
    else
        echo "Creating directory failed: $dir_name"
        return 1
    fi 
}

I aby go użyć:

create_clean_directory <dir_name>

To gwarantuje, że to, co próbujesz usunąć, to katalog, a nie plik:

  1. -dSprawdź, czy katalog o tej nazwie już istnieje. jeśli tak, usuń go.

  2. -fSprawdź, czy nie istnieje plik o tej nazwie. jeśli tak, wydrukuj komunikat o błędzie i zakończ.

  3. Utwórz nowy katalog i powodzenie echa, a jeśli nie powiodło się, echo nie powiodło się.

Rea Haas
źródło