Bagaimana Anda menyalin direktori di Linux dalam situasi ini menggunakan cp?

4

Situasi 1

Bagaimana cara menyalin /home/src/somedirke /dest/sehingga jalan selalu berakhir sebagai /dest/somedir, terlepas dari apakah /dest/somedirsudah ada?

Saya ingin menghindari berakhir dengan /dest/somedir/somedir.

Situasi 2

Bagaimana cara menyalin segala sesuatu di dalam /home/src/somediruntuk /dest/sehingga /dest/somedirtidak diciptakan dan diabaikan jika sudah ada?


Apakah ada aturan tentang garis miring yang dapat saya gunakan? Saya pikir mengakhiri dengan garis miring berarti selalu menyalin isinya saja tetapi masih sering salah bagi saya.

Orang
sumber
1
apa yang khusus Anda maksud dengan "diabaikan"? Anda ingin salinannya berlanjut atau dibatalkan? cp -r /home/src/somedir /dest/harus mengatasi kedua situasi, baik membuat atau menggabungkan ke folder yang ada
Frank Thomas
Apakah harus dengan cp? Mungkin ada opsi yang benar untuk rsyncmelakukan ini.
Barmar

Jawaban:

7

cpakan selalu menyalin file pada awal perintah ke file atau direktori pada akhir perintah. Slash tidak terlalu berpengaruh pada argumen, kecuali argumennya adalah symlink ke direktori. Kemudian memiliki garis miring akan memperlakukannya seperti direktori sementara menghilangkan garis miring akan menyalin tautan itu sendiri.

Dengan asumsi Anda ingin menyalin secara berulang subdirektori dalam contoh Anda, Anda akan menyukainya seperti:

cp -r /home/src/somedir /dest

dan

cp -r /home/src/somedir/* /dest

Yang pertama mendapatkan direktori /home/src/somedirdan akan menyalin argumen itu, direktori itu sendiri dan semua isinya, ke argumen terakhir /dest,. Ini akan membuat somedirdirektori /destjika diperlukan dan menggunakannya jika sudah ada.

The addes kedua *sampai akhir argumen pertama, yang shell akan memperluas untuk menjadi setiap file yang tidak dimulai dengan .di /home/src/somedirdan akan menyalin semua file-file dan direktori untuk /desttanpa memperhatikan apa yang sudah ada (kecuali beberapa bendera untuk cpakan membuatnya meminta untuk menimpa file yang akan memiliki yang sama di dalam tujuan sebagai file yang ada).

Seperti komentar yang ditunjukkan oleh jawaban ini, ada masalah dalam menggunakan *untuk mengambil semua file di direktori. Salah satu alternatif adalah menggunakan tarsalinan untuk Anda

tar -c -C /home/src/somedir . | tar -x -C /dest

ini akan membuat file tar somedirtanpa lintasan terkemuka dengan menggunakan -Cuntuk beralih ke direktori itu terlebih dahulu. Secara default tarakan mencetak stdoutyang kemudian kami pipa ke yang lain taruntuk mengekstraknya beralih ke /destdirektori yang diinginkan terlebih dahulu. Ini juga akan mempertahankan banyak atribut file, yang cpdapat melakukannya juga.

Eric Renouf
sumber
2
Patut dicatat bahwa *ekspansi wildcard akan gagal jika ada terlalu banyak pertandingan. Saya tidak tahu angka pastinya, tetapi terakhir kali saya gagal, direktori tersebut memuat sekitar 100.000 file / direktori.
Aleks G
Poin baiknya, juga jika tidak ada file secara default akan mencoba untuk menyalin file bernama*
Eric Renouf
Memang, jadi dalam skrip tingkat produksi Anda akan menambahkan semua cek ini.
Aleks G
Yap pasti ingin menghindari wildcard mengingat itu tidak menyalin file tersembunyi dan memiliki masalah dengan cara memperluas di shell.
Orang
@AlexG dan @Person memberikan pengamatan kesulitan dengan gumpalan saya menyertakan alternatif yang tidak digunakan cptetapi harus menyelesaikan tugas
Eric Renouf
2

Bagaimana cara menyalin / home / src / somedir ke / dest / sedemikian rupa sehingga jalan selalu berakhir sebagai / dest / somedir, terlepas dari apakah / dest / somedir sudah ada?

cp -rv /home/src/somedir /dest

Kami menyalin «somedir» ke «/ dest», jadi kami berakhir dengan «/ dest / somedir»

Bagaimana cara menyalin segala sesuatu di dalam / home / src / somedir ke / dest / sedemikian rupa sehingga / dest / somedir tidak dibuat dan diabaikan jika sudah ada?

cp -rv /home/src/somedir/* /dest

Kami menyalin «semua file di somedir» ( somedir/*) ke «/ dest»

Peringatan: somedir / * tidak termasuk file tersembunyi (yang diawali dengan titik).

Garis miring terakhir tidak memengaruhi proses. Anda mungkin bingung cpdengan rsync, di mana garis miring berarti "menyalin konten, bukan folder".

Malaikat
sumber
Saya pikir jawaban ini tidak memiliki penjelasan tentang penggunaan titik jejak untuk mencapai menyalin file.
Orang