Làm thế nào để sao chép với cp để bao gồm các tệp ẩn và thư mục ẩn và nội dung của chúng?


326

Làm thế nào tôi có thể làm cp -r bản sao hoàn toàn tất cả của các tập tin và thư mục trong một thư mục

Yêu cầu:

  • Bao gồm các tập tin ẩn và thư mục ẩn.
  • Là một lệnh duy nhất với một cờ để bao gồm ở trên.
  • Không cần phải dựa vào khớp mẫu nào cả.

Tôi xấu xí, nhưng làm việc, hack là:

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

Làm thế nào tôi có thể làm tất cả điều này trong một lệnh mà không có mẫu phù hợp? Tôi cần sử dụng cờ nào?


1
Nhiều câu trả lời ở đây, mặc dù chúng không có vẻ tốt; serverfault.com/questions/3154/
Roel Van de Paar

Xin vui lòng, Eleven81, xem xét thay đổi câu trả lời được chấp nhận cho câu trả lời của @bruno pereira, vì nó tránh tạo thư mục mới. Nếu không, hãy để bình luận này là một cảnh báo cho độc giả mới để kiểm tra câu trả lời khác (được bình chọn nhiều nhất). Tx.
Dr Beco

Câu trả lời:


234

Không chỉ định các tệp:

cp -r /etc/skel /home/user

(Lưu ý rằng /home/user không được tồn tại, nếu không nó sẽ tạo ra /home/user/skel.)


51
Có thể sử dụng một cái gì đó tương tự nếu /home/user/skel làm hiện hữu?
bradley.ayers

@ bradley.ayers Tôi nghĩ rằng người ta có thể sao chép vào thư mục con tạm thời sau đó chuyển chúng lên cấp trên (vì di chuyển trong cùng một ổ đĩa là nhanh). Ít hơn lý tưởng, nhưng ngắn hơn các giải pháp khác với tôi.
Halil Özgür

7
@ bradley.ayers Câu trả lời của Bruno dưới đây giải quyết câu hỏi của bạn
Mark

1
Giải pháp này không hiệu quả với tôi. Nó không sao chép các tập tin ẩn. Tôi đang sử dụng phiên bản CentOS 6.5. @ Giải pháp của Bruno đã làm điều đó.
Technext

2
Trong ubfox / debian, điều này đặt thư mục 'skel' bên trong thư mục đích chứ không phải các tệp được đệ quy bên trong skel. Sử dụng -T (không có mục tiêu) mỗi bên dưới để sử dụng đúng. ( -rT cho đệ quy)
bshea

420

Hãy nói rằng bạn đã tạo thư mục mới (hoặc sẽ tạo một thư mục) và muốn sao chép các tệp vào thư mục đó sau khi thư mục được tạo

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

Điều này sẽ sao chép tất cả các tệp / thư mục đệ quy từ /etc/skel vào thư mục đã tồn tại được tạo trên dòng đầu tiên.


4
Nếu tôi không hiểu sai, điều này đã không sao chép các tập tin ẩn / dấu chấm.
Halil Özgür

28
Hoạt động tốt cho tôi. Lưu ý rằng '.' là rất quan trọng để nó làm việc.
Mark

11
Nó hoạt động, nhưng, tại sao? Không thể tìm thấy tài liệu tham khảo này trong hướng dẫn.
Julien Palard

5
Tôi nghĩ rằng nó hoạt động bởi vì thông thường, điều này sẽ tạo ra một thư mục mới với tên của thư mục cuối cùng trong đối số đầu tiên. Tuy nhiên, vì tên đó là ., hành vi này sẽ yêu cầu nó tạo một thư mục đã tồn tại, vì vậy nó chỉ bỏ qua bước đó.
Zenexer

21
@Technext Toàn cầu mặc định trong bash không bao gồm tên tệp bắt đầu bằng một ., để thay đổi rằng bạn cần sử dụng shopt -s dotglob lệnh trước để có thể bao gồm các tập tin. Vì vậy *theo mặc định, bạn đang yêu cầu sao chép tất cả các tệp đệ quy từ thư mục này có thể được mở rộng bằng cách sử dụng * (không bao gồm các tập tin ẩn theo mặc định). Trong khi ở đầu bên kia với . bạn đang sử dụng cp để sao chép đệ quy mọi thứ từ "thư mục này".
Bruno Pereira

64

bash bản thân nó có một giải pháp tốt, nó có một shell option, Bạn có thể cp, mv và như vậy:

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

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

Giải pháp trên là tiêu chuẩn của bash

CHÚ THÍCH:

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

2
Điều đó hữu ích khi bạn muốn sao chép chỉ nội dung mà không tạo thư mục mới bên trong đích. Đặc biệt khi dir đích là điểm gắn kết.
kaszynek

3
Đây thực sự là câu trả lời hay nhất và đi vào trọng tâm của câu hỏi ..
Stephen

6
nó là setopt cho zsh, trong trường hợp bất cứ ai khác đang tự hỏi.
Pat

57

Phương tiện chính xác để làm điều này là sử dụng -T (--no-target-directory) tùy chọn và sao chép đệ quy các thư mục (không có dấu gạch chéo, dấu sao, v.v.), tức là:

cp -rT /etc/skel /home/user

Điều này sẽ sao chép nội dung của /etc/skel đến /home/user (bao gồm các tập tin ẩn), tạo thư mục /home/user nếu nó không tồn tại; tuy nhiên -T tùy chọn ngăn nội dung của /etc/skel từ bị sao chép sang một thư mục mới /home/user/skel thư mục nên /home/user hiện hữu.


2
Câu trả lời chính xác. +1
bshea

đây thực sự là câu trả lời đúng
Gaetan

đây là câu trả lời TỐT NHẤT của bó; nó là người duy nhất giải quyết vấn đề mà không làm phức tạp nó
ZaxLofful

23

Sử dụng rsync:

rsync -rtv source_folder/ destination_folder/


Tùy chọn tốt nhất cho tôi, mặc dù tôi sử dụng - tiến hành để có thêm phản hồi về toàn bộ quá trình.
Edenshaw

3

Nếu thư mục nguồn và đích của bạn có cùng tên, ngay cả khi thư mục đích tồn tại, bạn chỉ cần gõ:

cp -R /etc/skel /home/

Điều này sẽ sao chép thư mục / etc / skel vào / home /, bao gồm các tệp và thư mục ẩn.

Cuối cùng, bạn có thể sao chép thư mục và đổi tên nó trong một dòng duy nhất:

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

Hoặc bạn có thể chỉ cần sử dụng cp -r /etc/skel /home/user để đổi tên skel đến user...
David

Điều đó đúng, chỉ khi / nhà / người dùng chưa tồn tại.
Gabriel Hautclocq

2

rsync là tốt, nhưng lựa chọn khác:

cp -a src/ dst/

Từ trợ giúp chính:

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

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

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

Tôi luôn sử dụng cp -r. Cảm ơn đã đề cập đến cp -a
Pinaki Mukherjee

2

Bạn có thể sử dụng rsync.

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

Bạn thậm chí có thể sao chép qua ssh

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

Có nhiều cờ bạn có thể sử dụng:     -a, --archive # lưu trữ (-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.

Trang người đàn ông


1

Lưu ý rằng có một thủ thuật dòng lệnh (ít nhất là hoạt động trong sh , bash ksh ): Chỉ hậu tố từ thư mục với một dấu gạch chéo. Điều này sẽ đổ nội dung của từ vào thư mục đến thư mục (trớ trêu thay, lần đầu tiên tôi đã biết về thủ thuật này khi sử dụng rsync ).

Thí dụ:

/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

1

Tôi đến đây nhờ Googled tìm giải pháp cho cùng một vấn đề, sau đó tôi nhận ra rằng việc tìm kiếm rất dễ dàng. Ưu điểm của nó không phụ thuộc vào trình bao hoặc các tiện ích đặc biệt có thể không được cài đặt.

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

Tôi đã thử mẹo với dấu gạch chéo, nhưng nó không hiệu quả với tôi.


1

Giải pháp của tôi cho vấn đề này khi tôi phải sao chép tất cả các tập tin (kể cả . tập tin) vào một thư mục đích giữ quyền là: (ghi đè nếu đã tồn tại)

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

yes là để tự động ghi đè tập tin đích, r đệ quy, v dài dòng p giữ quyền.

Lưu ý rằng đường dẫn nguồn không kết thúc bằng một / (vì vậy tất cả các tệp / thư mục và tệp. được sao chép)

Thư mục đích kết thúc bằng / vì chúng tôi đang đặt nội dung của thư mục nguồn tới đích.


1

Cách đơn giản nhất là:

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

Cách diễn đạt {.,}* bao gồm tất cả các tệp và thư mục (cũng bắt đầu bằng dấu chấm).

Nếu bạn không muốn sử dụng biểu thức trên, thì bạn có thể sử dụng cp thuộc tính, đó là khả năng chỉ định nhiều nguồn cho một thư mục đích:

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

điều này sẽ bỏ lỡ các tập tin như ..anything hoặc là ...anything v.v. - stackoverflow.com/a/31438355/2351568 chứa regex chính xác cho vấn đề này. | | nhưng dù sao sử dụng shopt -s dotglob vẫn là giải pháp tốt hơn!
DJCrashdummy

@DJCrashdummy thật không may, tôi không hiểu tại sao bạn viết sự chú ý của bạn. Rốt cuộc, giải pháp của tôi có tính đến các trường hợp bạn viết về. Trân trọng
simhumileco

xin lỗi văn bản sai! - vấn đề với câu trả lời của bạn là, nó cũng sẽ xem xét ... (tương đương với thư mục hiện tại và thư mục chứa nó). | | nhưng vẫn trả lời trong liên kết giải thích thêm và cung cấp một giải pháp.
DJCrashdummy

-2

Trong ít nhất K3b 2.0.3, có một hộp câu hỏi bật lên khi thư mục được thêm vào dự án, hỏi bạn có muốn bao gồm các tệp ẩn không ... cũng có một câu hỏi bật lên để hỏi về bao gồm liên kết. Dụng cụ tốt!


"một hộp câu hỏi bật lên" - cho lệnh shell (CLI)?
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.