Salin konten direktori menggunakan perintah 'cp'

33

Bagaimana Anda menyalin semua konten dari satu direktori ke direktori lain?

Sebagai contoh:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

Masalah dengan hal di atas adalah bahwa pola globing '*' cocok dengan direktori tersembunyi '.' dan '..' dan Anda berakhir dengan direktori 'pengguna lama' di dalam 'pengguna baru', serta kontennya.

Anda juga dapat melakukan sesuatu seperti ini:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

Tetapi bagaimana jika pengguna baru sudah mengandung beberapa file dan direktori default?

Apa yang paling sederhana, paling benar, paling mudah diingat dan bukan cara mess-up untuk memindahkan konten dari satu direktori ke direktori lain hanya dengan menggunakan perintah 'cp' dan shell?

Der Hochstapler
sumber

Jawaban:

31

Mencoba:

cp -ra /backup/olduser/. /home/newuser
Nagul
sumber
Ini bagus, tapi saya tidak tahu persis cara kerjanya. Saya pikir itu mungkin karena saya tidak mengerti bagaimana .dan ..bekerja. Mau jelaskan?
bradley.ayers
Ini bekerja untuk saya tetapi cp -r ./a btidak. Ada yang tahu kenapa?
Brig
3
bekerja untuk saya juga, tetapi ropsi tidak diperlukan. The apilihan menyiratkan r.
MountainX
1
parameter -r tampaknya agak berlebihan pada saat ini!
Master of Celebration
The -aparameter tidak apa-apa untuk membantu dalam situasi ini. Perintah cp -r ./a/. bakan menyalin konten, dan hanya konten, direktori ake direktori b. The -abendera mempertahankan link, cap waktu dll, yang tidak relevan dengan pertanyaan.
Steen Schütt
23

Dua direktori a dan b.

Keduanya memiliki file.

Anda berada di direktori yang berisi a dan b.

cp -r ./a b

-r = secara rekursif.

Bradshaw yang kaya
sumber
Apakah Anda tidak ingin -a mendapatkan semua file?
bw
7
Argumen -a tidak ada hubungannya dengan semua file, ini adalah kependekan dari arsip, itu akan mempertahankan kepemilikan file, izin, waktu akses dll. Argumen -a (walaupun sangat berguna) bukanlah opsi standar, dan beberapa implementasi cp tidak dapat menyediakannya.
theotherreceive
1
@mch: disertakan secara otomatis, karena Anda telah diberitahu cpuntuk menyalin direktori a, dan a/.somedotfileberisi oleh a. jika bada, perintah ini akan membuat salinan persis aat b/a.
Quack quixote
2
Cara mudah:cp -R /some/dir/* /another/dir
n0pe
1
Ini menyalin / foo ke b / a / foo alih-alih ke b / foo
Sparr
19

Ingat bahwa, secara default, cpmenyalin direktori pertama ke direktori kedua jika direktori kedua ada.

Misalnya cp -r a bakan menyalin direktori a ke b. Jika btidak ada, itu akan dibuat dengan konten a.

Jika Anda ingin menyalin isi dari adalam b(misalnya ketika menyalin seluruh filesystem menjadi mount point) penggunaan:

cp -r a/. b

seperti pada jawaban sebelumnya.

Harap perhatikan juga bahwa -a, yang digunakan dalam beberapa jawaban lain, sama dengan -dr --preserve=alldan akan mempertahankan cap waktu, konteks, dan atribut yang diperluas.

Nicolas Bonnefon
sumber
Bagaimana cara /.kerjanya?
bradley.ayers
a/.mewakili konten direktori 'a' sebagai lawan dari direktori itu sendiri, dalam sebagian besar situasi itu identik tetapi ketika menggunakan cp -r, itu menghindari perilaku default cp (menyalin INTO b).
Nicolas Bonnefon
tip luar biasa, ini persis apa yang saya cari tetapi gagal menemukan tempat lain - semua itu 'foo / *' atau '-r foo /' yang gagal dalam kasus sudut.
Tener
@TimoHuovinen '.' sama sekali bukan wildcard. Secara harfiah direktori "induk", dan '..' adalah kakek-nenek. Ini berarti '/foo/./././././.' adalah direktori yang sama dengan '/ foo', dan '/ foo / bar / ..' adalah direktori yang sama dengan '/ foo'. Anggap mereka sebagai hardlink yang dibangun ke sistem file.
quuxman
@quuxman terima kasih, saya tidak menyadarinya saat itu. Saya akan menghapus komentar lama saya untuk menghindari orang yang membingungkan.
Timo Huovinen
6

Kecuali Anda telah mengkonfigurasi ulang shell Anda dengan serius, pola globbing '*' tidak cocok '.' atau '..', karena Anda dapat memverifikasi hanya dengan menggunakan gema *. Apa yang dilakukan sebagai gantinya adalah menghilangkan file yang namanya dimulai dengan '.', Sehingga pendekatan Anda akan kehilangan semua file tersembunyi. Anda bisa mengubah beberapa perilaku ini dengan opsi shell, misalnya opsi dotglob di bash, tetapi itu tidak akan menjadi opsi portabel dan kuat yang Anda cari.

Jika Anda perlu melakukan ini lebih dari sekali atau dua kali, saya sarankan Anda melihat rsync atau serempak (tergantung pada kebutuhan spesifik) dengan spesifikasi sumber dan target yang dibuat dengan cermat.

Alternatif lain adalah menempatkan direktori sumber di tarball dan membukanya di atas direktori target yang ada.

Peter Eisentraut
sumber
1
saya menggunakan ini: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... tar cf - .tar adalah direktori sumber, termasuk dotfile, dan meludahkannya ke STDOUT, yang akan disalurkan ke STDIN dari tar xf -.
quack quixote
Saya pikir inti dari OP adalah bagaimana merujuk file yang dimulai dengan '.' tapi bukan yang spesial '.' dan direktori '..'. Ada solusi yang jauh lebih elegan di atas daripada menggunakan rsync atau program kompleks lainnya.
quuxman
2

Ini akan menyalin file normal dan tersembunyi, sambil mengecualikan direktori induk ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

Jika Anda tidak mengecualikan direktori induk, Anda berakhir dengan semua konten ..di direktori tujuan Anda juga.

mch
sumber
1
Tetapi ini masih mengecualikan nama yang dimulai dengan .. (misalnya, ...atau ..super-hidden).
Scott
0

Untuk menyalin file yang dimulai dengan titik, lakukan saja cp. * Target /

Jadi yang paling mudah adalah dengan melakukan perintah cp dua kali.

Seperti Peter Eisentraut sais, aturan globbing normal tidak termasuk .. dan. (hm, bagaimana cara mengakhiri kalimat ini?;)

Cukup gunakan -r untuk membuatnya rekursif dan -i untuk membuat cp tanyakan apakah Anda benar-benar ingin menimpa file.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/
gaqzi
sumber
Biasanya *tidak cocok .atau .., tetapi jika Anda gunakan .*. Coba echo .*. Anda dapat mengecualikan .dan ..dengan pola berikut: .[^.]*.
mch
@mch: Tetapi .[^.]*masih mengecualikan nama yang dimulai dengan .. (misalnya, ...atau ..super-hidden).
Scott
0

Ini berfungsi untuk menyalin semua file dan direktori kecuali untuk direktori tersembunyi secara rekursif dari direktori saat ini ke mana pun:

cp -rf * ^.* 
Seeeve
sumber