Właśnie zacząłem używać BASH, więc mogę przenieść całą zawartość katalogu do innego. Ale problem polega na tym, że spodziewałem się, że połączy katalogi. Używam zadania cron do uruchomienia tego skryptu.
#!/bin/bash
shopt -s dotglob nullglob
mv mv_schedule/* public_html/
Źródło: /mv_schedule/
(zawierające foldery / pliki)
/files/
4.html
5.html
/assets/
sitemap.xml
Miejsce docelowe: /public_html/
(poprzednie foldery już istnieją)
/files/
1.html
2.html
3.html
/assets/
sitemap.xml
Chcę więc, aby wszystkie nowe pliki z tych katalogów w środku /mv_schedule/
połączyły się z plikami wewnątrz /public_html/
, a pliki, które już tam są, zostały zastąpione plikami pochodzącymi /mv_schedule/
.
Obecnie zwraca ten błąd przez e-mail, gdy próbuję tego z bieżącym skryptem:
mv: cannot move `mv_schedule/assets' to `public_html/assets': Directory not empty
Jak mogę to naprawić?
alias -a
/Odpowiedzi:
Komunikat o błędzie mówi ci, że nie można przenieść katalogu zasobów, ponieważ są w nim pliki. mv katalog oznacza wykonanie kopii, a następnie skasowanie i nie można go usunąć, ponieważ nadal zawiera niektóre pliki. Oznacza to, że powinieneś również zapisać pliki wewnątrz zasobu, a nawet podkatalogi i pliki w podkatalogach w zasobie, jeśli istnieją. Ale wydane polecenie mv może tylko kopiować (i wymazywać) to, co jest obecne w katalogu mv_schedule, a nie to, co jest obecne w podkatalogach (jak zasób) w mv_schedule.
To, czego chcesz, to polecenie, które obniża drzewo katalogów do ostatniego liścia i kopiuje je, coś w rodzaju opcji -r lub -R w rm, chmod, chown. Jednak mv nie ma takiej opcji, więc będziesz musiał użyć polecenia find, które zstępuje z całego drzewa katalogów od określonego katalogu głównego, a następnie wykonuje określone działanie. W twoim przypadku odpowiednie polecenie to:
Spowoduje to spiętrzenie wszystkich plików w jednym katalogu docelowym. Zakłada się, że przekazałeś katalog źródłowy i docelowy jako parametry wiersza wejściowego do skryptu bash. Opcja -f zapobiega pytaniu o potwierdzenie w przypadku zastąpienia, możesz zmienić to na -n (nie zastępuj) lub -i (pytaj przed zastąpieniem).
Jeśli zamiast tego chcesz zachować strukturę katalogów, pamiętaj, że polecenie cp ma możliwość zejścia z drzewa katalogów, dzięki czemu możesz użyć tego, a następnie komendy rm, ponieważ to polecenie ma również możliwość zejścia z drzew. Jednym z możliwych zestawów poleceń jest:
Zwróć uwagę na opcję -a w cp: zachowuje znaczniki czasu i własność. Jeśli nie przejmujesz się takimi rzeczami, możesz zamiast tego użyć opcji -R.
źródło
SOURCE_DIR
iTARGET_DIR
zdirName/
? Widzę też, że wspomniałeś -i (zapytaj przed nadpisaniem). Chcę, aby zastąpił istniejące pliki i scalił z istniejącymi katalogami, aby wszystkie istniejące pliki były w katalogu docelowym i dodawać (również zastępować istniejące pliki) nowe z tego samego katalogu nazw ze źródła.rm -rf $SOURCE_DIR
usunie katalog źródłowy, być może lepiej go zachować i używaćrm -rf "$SOURCE_DIR/*"
- Zaleca się również stosowanie cudzysłowów wokół zmiennych (w przypadku gdy w nazwach katalogów występują spacje)/mv_schedule/, not the directory
/ mv_schedule / `.Bardziej ogólna dyskusja na temat tego problemu znajduje się w sekcji Uniksa.
Możesz użyć
-l
opcji polecenia cp , która tworzy twarde łącza plików w tym samym systemie plików zamiast kopii pełnych danych. Następujące polecenie kopiuje foldersource/folder
do folderu nadrzędnego (destination
), który już zawiera katalog o nazwiefolder
.Uwagi:
-P
(--no-dereference
- nie usuwaj odsyłaczy symbolicznych) lub-a
(--archive
- zachowaj wszystkie metadane, w tym także-P
opcję), w zależności od potrzeb.-l
rozwiązanie oparte na cp (sans ) lub rsync.źródło
Doskonała odpowiedź od palswim. (Również dzięki za głosowanie za te dwa ostatnie punkty potrzebne, aby móc głosować sam!)
CP-R1; rm rozwiązuje problem i przy minimalnym We / Wy (cp i rsync są pod tym względem głupio drogie).
Są z tym dwa drobne problemy:
źródło