Jak skopiować za pomocą cp, aby dołączyć ukryte pliki i ukryte katalogi i ich zawartość?


392

Jak mogę cp -rskopiować absolutnie wszystkie pliki i katalogi w katalogu

Wymagania:

  • Dołącz ukryte pliki i ukryte katalogi.
  • Być jednym poleceniem z flagą zawierającą powyższe.
  • W ogóle nie trzeba polegać na dopasowaniu wzorów.

Mój brzydki, ale działający hack to:

cp -r /etc/skel/* /home/user
cp -r /etc/skel/.[^.]* /home/user

Jak to zrobić w jednym poleceniu bez dopasowania wzorca? Jakiej flagi muszę użyć?


1
Więcej odpowiedzi tutaj, choć nie wyglądają tak dobrze; serverfault.com/questions/3154/…
Roel Van de Paar

Proszę, Eleven81, rozważ zmianę zaakceptowanej odpowiedzi na udzieloną przez @bruno pereira, ponieważ pozwala to uniknąć tworzenia nowego folderu. Jeśli nie, niech ten komentarz będzie ostrzeżeniem dla nowych czytelników, aby sprawdzili także drugą (najczęściej głosowaną) odpowiedź. TX
Dr Beco,

Odpowiedzi:


265

Nie określaj plików:

cp -r /etc/skel /home/user

(Pamiętaj, że /home/usernie może już istnieć, w przeciwnym razie stworzy /home/user/skel).


61
Czy jest możliwe aby użyć coś podobnego, jeśli /home/user/skel nie istnieje?
bradley.ayers

@ bradley.ayers Myślę, że można skopiować do tymczasowego podkatalogu, a następnie przenieść je na wyższy poziom (ponieważ poruszanie się po tym samym dysku jest szybkie). Mniej niż idealne, ale krótsze niż inne rozwiązania dla mnie.
Halil Özgür

7
@ bradley.ayers Poniższa odpowiedź Bruno dotyczy twojego pytania
Mark

1
To rozwiązanie nie działało dla mnie. Nie skopiował ukrytych plików. Korzystam z CentOS wersja 6.5. @ Rozwiązanie Bruno załatwiło sprawę.
Technext,

2
Pod Ubuntu / debian umieszcza katalog „skel” w katalogu docelowym, a nie pliki cykliczne w skel. Użyj -T(bez celu) poniżej dla poprawnego użycia. ( -rTdla rekurencyjnych)
bshea

468

Powiedzmy, że utworzyłeś nowy folder (lub zamierzasz go utworzyć) i chcesz skopiować pliki do niego po utworzeniu folderu

mkdir /home/<new_user>
cp -r /etc/skel/. /home/<new_user>

Spowoduje to skopiowanie rekursywnie wszystkich plików / folderów z /etc/skeldo istniejącego folderu utworzonego w pierwszym wierszu.


5
Jeśli nie pomyliłem się, nie kopiowałem plików ukrytych / kropkowych.
Halil Özgür,

34
Działa dla mnie dobrze. Zauważ, że „.” ma kluczowe znaczenie dla jego działania.
Mark

12
Działa, ale dlaczego? Nie można znaleźć odniesienia do tego w instrukcji.
Julien Palard

5
Myślę, że to działa, ponieważ normalnie utworzyłby to nowy folder z nazwą ostatniego folderu w pierwszym argumencie. Ponieważ jednak ma taką nazwę ., takie zachowanie wymagałoby utworzenia już istniejącego katalogu, więc po prostu pomija ten krok.
Zenexer

28
@Technext Domyślne globowanie w bash nie obejmuje nazw plików rozpoczynających się od a ., aby zmienić to, że musisz użyć shopt -s dotglobpolecenia, aby móc dołączyć te pliki. Tak więc *domyślnie pytasz o skopiowanie wszystkich plików rekurencyjnie z tego katalogu, który można rozwinąć za pomocą *(który domyślnie nie obejmuje plików ukrytych). Podczas gdy z drugiej strony .używasz cp do rekurencyjnego kopiowania wszystkiego z „tego katalogu”.
Bruno Pereira,

79

Prawidłowym sposobem na to jest skorzystanie z -T (--no-target-directory)opcji i rekurencyjne kopiowanie folderów (bez końcowych ukośników, gwiazdek itp.), Tj .:

cp -rT /etc/skel /home/user

Spowoduje to skopiowanie zawartości /etc/skeldo /home/user(w tym pliki ukryte), tworząc folder /home/user, jeśli nie istnieje; jednak ta -Topcja uniemożliwia /etc/skelskopiowanie zawartości do nowego folderu, /home/user/skeljeśli folder /home/useristnieje.


3
Poprawna odpowiedź. +1
bshea

to była rzeczywiście właściwa odpowiedź
Gaetan

to jest NAJLEPSZA odpowiedź w grupie; jest to jedyny, który rozwiązuje problem bez komplikowania go
ZaxLofful,

dokładnie działa zgodnie z oczekiwaniami
Chetabahana

Uwielbiam to, gdy używasz poprawnej flagi cmd dla jednego przypadku.
Tran Triet

66

bashSam ma dobre rozwiązanie, posiada shell option, można cp, mvi tak dalej .:

shopt -s dotglob # for considering dot files (turn on dot files)

i

shopt -u dotglob # for don't considering dot files (turn off dot files)

Powyższe rozwiązanie jest standardem bash

UWAGA:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set

2
Jest to przydatne, gdy chcesz skopiować tylko zawartość bez tworzenia nowego katalogu w miejscu docelowym. Zwłaszcza, gdy katalog docelowy jest punktem montowania.
kaszynek

3
To naprawdę najlepsza odpowiedź i trafia do sedna pytania ...
Stephen

7
To jest setoptdla Zsh, na wypadek, gdyby ktokolwiek się zastanawiał.
Pat

25

Użyj rsync:

rsync -rtv source_folder/ destination_folder/


Najlepsza opcja dla mnie, chociaż używam --progress, aby uzyskać więcej opinii na temat całego procesu.
Edenshaw

5

rsync jest dobry, ale inny wybór:

cp -a src/ dst/

Z głównej pomocy:

   -a, --archive
          same as -dR --preserve=all

   -d     same as --no-dereference --preserve=links

   -R, -r, --recursive
          copy directories recursively

Zawsze używałem cp -r. Dzięki za wzmiankę o cp -a
Pinaki Mukherjee

4

Jeśli katalog źródłowy i docelowy mają tę samą nazwę, nawet jeśli istnieje katalog docelowy, możesz po prostu wpisać:

cp -R /etc/skel /home/

Spowoduje to skopiowanie katalogu / etc / skel do / home /, w tym ukrytych plików i katalogów.

W końcu możesz skopiować katalog i zmienić jego nazwę w jednym wierszu:

cp -R /etc/skel /home/ && mv /home/skel /home/user

Lub możesz po prostu użyć cp -r /etc/skel /home/userdo zmiany nazwy skelna user...
David

Zgadza się, tylko jeśli / home / user jeszcze nie istnieje.
Gabriel Hautclocq

4

Możesz użyć rsync.

rsync -aP ./from/dir/ /some/other/directory/

Możesz nawet skopiować przez ssh

rsync -aP ./from/dir/ username@remotehost:/some/other/directory/

Można użyć różnych flag: -a, --archive # archive (-rlptgoD)

-r, --recursive
-l, --links      # copy symlinks as links
-p, --perms      # preserve permissions
-t, --times      # preserve times
-g, --group      # preserve group
-o, --owner      # preserve owner
-D               # --devices --specials

--delete         # Delete extra files

You may want to add the -P option to your command.

--partial        # By default, rsync will delete any partially transferred file if the transfer is interrupted. In some circumstances it is more desirable to keep partially transferred files. Using the --partial option tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.

-P               # The -P option is equivalent to --partial --progress.   Its  purpose  is to make it much easier to specify these two options for a long transfer that may be interrupted.

Strona podręcznika Rsync


4

Najprostszym sposobem jest:

cp -r /etc/skel/{.,}* /home/user

Wyrażenie {.,}*obejmuje wszystkie pliki i katalogi (również zaczynające się od kropki).

Jeśli nie chcesz używać powyższego wyrażenia, możesz użyć cpwłaściwości, która umożliwia określenie wielu źródeł dla jednego folderu docelowego:

cp -r /etc/skel/* /etc/skel/.* /home/user

1
to minie jak pliki ..anythinglub ...anythingetc. - stackoverflow.com/a/31438355/2351568 zawiera prawidłowy regex tego problemu. || ale i tak używanie shopt -s dotglobjest nadal lepszym rozwiązaniem!
DJCrashdummy

@DJCrashdummy niestety nie rozumiem, dlaczego napisałeś swoją uwagę. W końcu moje rozwiązanie uwzględnia przypadki, o których piszesz. Pozdrawiam
simhumileco

przepraszam, zły tekst! - problem z twoją odpowiedzią polega na tym, że weźmie również pod uwagę .i ..(co jest równoważne z bieżącym i zawierającym go folderem). || ale odpowiedź w linku wyjaśnia to dalej i stanowi rozwiązanie.
DJCrashdummy,

2

Zauważ, że istnieje sztuczka z wiersza poleceń (działa przynajmniej w sh , bash i ksh ): Po prostu dodaj przyrostek z katalogu ukośnikiem. Będzie to wlać zawartość z katalogu do do katalogu (jak na ironię, że po raz pierwszy dowiedział się o tej sztuczki przy użyciu rsync ).

Przykład:

/tmp$ mkdir test_dir1
/tmp$ cd test_dir1/
/tmp/test_dir1$ touch aa
/tmp/test_dir1$ touch .bb
/tmp/test_dir1$ cd ..
/tmp$ mkdir test_dir2

/tmp$ cp -r test_dir1/* test_dir2
/tmp$ ls -1a test_dir2
.
..
aa

/tmp$ cp -r test_dir1/ test_dir2
/tmp$ ls -1a test_dir2
.
..
.bb
aa

2

Przyszedłem tu, szukając rozwiązania tego samego problemu w Google, a potem zdałem sobie sprawę, że łatwo jest znaleźć. Zaleta nie zależy od powłoki ani specjalnych narzędzi, które mogą nie zostać zainstalowane.

find /etc/skel/ -mindepth 1 -exec cp -r {} /home/username/ \;

Próbowałem tej sztuczki z końcowym cięciem, ale to nie działało dla mnie.


2

Moje rozwiązanie tego problemu, gdy muszę skopiować wszystkie pliki (w tym .pliki) do katalogu docelowego z zachowaniem uprawnień to: (nadpisz, jeśli już istnieje)

yes | cp -rvp /source/directory /destination/directory/

yessłuży do automatycznego nadpisywania plików docelowych, rrekurencyjnych, vpełnych, pzachowania uprawnień.

Zauważ, że ścieżka źródłowa nie kończy się na/ (więc wszystkie pliki / katalog i. Pliki są kopiowane)

Katalog docelowy kończy się wraz z/ umieszczeniem zawartości folderu źródłowego jako miejsca docelowego jako całości.


1

Widziałem, że cp nie zawsze kopiuje ukryte pliki i jeśli chcesz komendy, która wydaje się działać we wszystkich dialektach linux / unix, powinieneś spróbować użyć:

cd /etc/skel
find | cpio -pdumv /home/user

-2

Od wersji co najmniej K3b 2.0.3 pojawia się okienko z pytaniami, które pojawia się po dodaniu katalogu do projektu, które pyta, czy chcesz dołączyć ukryte pliki ... pojawia się również pytanie, które należy zapytać o dołączenie spinki do mankietów. Niezłe rzeczy!


„wyskakujące okienko pytań” - dla polecenia powłoki (CLI)?
Scott
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.