scp tanpa mengganti file yang ada di tujuan

158

Bagaimana cara menyalin seluruh direktori ke direktori dengan nama yang sama tanpa mengganti konten di direktori tujuan? (sebagai gantinya, saya ingin menambahkan konten folder tujuan)

Daniel Böhmer
sumber
Ya, itu adalah menjengkelkan ketika program / utilitas yang berguna tidak memiliki satu yang "jika hanya bisa ..." pilihan! Dalam hal ini "--noclobber"!
MikeW

Jawaban:

139

Gunakan rsync, dan sampaikan -ujika Anda hanya ingin memperbarui file yang lebih baru di direktori asli, atau --ignore-existinguntuk melewati semua file yang sudah ada di tujuan.

rsync -au /local/directory/ host:/remote/directory/
rsync -a --ignore-existing /local/directory/ host:/remote/directory/

(Perhatikan /pada sisi sumber: tanpa itu rsyncakan membuat /remote/directory/directory.)

Gilles
sumber
@Anthon Saya tidak mengerti komentar Anda dan saya tidak melihat jawaban atau komentar oleh chandra. --ignore-existingtidak menambahkan tanpa mengganti, kehilangan data apa yang Anda lihat?
Gilles
Maaf, saya hanya melihat contoh pertama Anda yaitu di mana Anda dapat kehilangan data (dan bukan IMHO yang diminta OP), jika Anda menyertakan --ignore-data yang hilang tidak boleh terjadi.
Anthon
Ini tidak membantu jika sistem jarak jauh tidak rsyncdengan mudah tersedia .... (Seperti Win32-OpenSSH)
Gert van den Berg
@GertvandenBerg rsync cukup mudah untuk diinstal pada Windows, tidak lebih sulit dari SSH.
Gilles
@Gilles: Benar, tetapi semua opsi tampaknya melibatkan DLL Cygwin ... (Keadaan saat ini dari port MS OpenSSH sedemikian rupa sehingga memungkinkan kompresi pada scp cukup untuk menghancurkan SCP ...) (Mendapatkan fungsional rsync melalui Win32 -OpenSSH juga tampaknya non-sepele - mudah-mudahan itu membaik seiring waktu) (Solaris 10 adalah contoh lain, di mana paket pihak ketiga dan --rsync-pathdiperlukan)
Gert van den Berg
82

scp akan menimpa file jika Anda memiliki izin tertulis untuknya.

Dengan kata lain: Anda dapat scpsecara efektif melewati file-file tersebut dengan menghapus sementara waktu izin menulis padanya (jika Anda adalah pemilik file, itu adalah).

Reimund
sumber
5
Terima kasih untuk ini. Persis trik yang saya cari.
sakarin
pastikan Anda menyalin kembali file yang Anda tambahkan * untuk melakukannya. Contohscp -r [email protected]:/location/of/files/* /local/location/
Rick
1
Temukan . -type f -exec root chown: root {} \;
ling
1
Dalam kasus yang tidak umum bahwa hanya beberapa file dalam direktori diharapkan ditimpa (jika tidak "dilindungi"), dan izin file tidak seragam di seluruh file, solusi ini mungkin tidak berfungsi. Kalau tidak, itu cukup sederhana dan efektif.
sancho.s
Untuk melakukan ini pada windows pilih semua file, klik kanan -> properties -> read only
BenJammin
12

Anda hanya dapat menyalin file baru berdasarkan tanggal. Menggunakanfind

scp  `find /data/*.gz -type f -mtime +7` USER@SERVER:/backup/
Naks
sumber
apa arti +7?
Francis Kim
@FrancisKim artinya diubah 7 hari yang lalu. Jadi kueri ini pilih file * .gz apa pun yang diubah dalam 7 hari terakhir
Vadim Eremeev
4
Bukankah +7 sebenarnya menyiratkan lebih dari 7 hari yang lalu?
Jeff H.
1
Ya itu berarti "lebih dari 7 hari yang lalu". Tidak tahu siapa yang membatalkan ini.
Stefan Reich
9

Jika Anda dapat membuat konten file tujuan hanya-baca:

find . -type f -exec chmod a-w '{}' \;

sebelum dijalankan scp(itu akan mengeluh dan melewatkan file yang ada).

Dan mengubahnya kembali sesudahnya ( chmod +wuntuk mendapatkan nilai berbasis umask). Jika semua file tidak memiliki izin menulis sesuai dengan umask Anda, Anda harus menyimpan izin tersebut sehingga Anda dapat memulihkannya.

(Jawaban Gilles menimpa file yang ada jika secara lokal file tersebut lebih baru, saya kehilangan data berharga seperti itu. Tidak mengerti mengapa jawaban yang salah dan berbahaya memiliki begitu banyak suara).

Mohad
sumber
2
Saya tidak mengerti: bagaimana rsync --ignore-existingmenyebabkan Anda kehilangan data?
Gilles
4
Aku punya kesalahan find: missing argument to '-exec'menggunakan perintah ini, dan sebagai gantinya harus menggunakan: find . -type f -exec chmod a-w {} \;. Linux saya jelek, ymmv.
wpearse
Ini jawaban yang lebih baik dan lebih aman. Perintah yang benar untuk mengubah izin adalah seperti yang disebutkan @wpearse:find . -type f -exec chmod a-w {} \;
Amir
6

Aku punya tugas yang sama, dalam kasus saya saya tidak bisa menggunakan rsync, csyncatau FUSE karena penyimpanan saya hanya memiliki SFTP. rsynctidak dapat mengubah tanggal dan waktu untuk file, beberapa utilitas lain (seperti csync) menunjukkan kepada saya kesalahan lain: " Tidak dapat membuat file temporer Skew Jam terdeteksi ".

Jika Anda memiliki akses ke server penyimpanan - cukup instal openssh-serveratau luncurkan rsyncsebagai daemon di sini.

Dalam kasus saya - saya tidak bisa melakukan ini dan solusinya adalah: lftp . lftpPenggunaan untuk sinkronisasi di bawah ini:

lftp -c "open -u login,password sftp://sft.domain.tld/; \
    mirror -c --verbose=9 -e -R -L /srs/folder /rem/folder"

/src/folder- adalah folder di PC saya, /rem/folder- is sftp://sft.domain.tld/rem/folder.

Anda dapat menemukan halaman manual melalui tautan: http://lftp.yar.ru/lftp-man.html

mencolok
sumber
6

Untuk menyalin sejumlah besar file, lebih cepat untuk menaruhnya. Dengan menggunakan -k Anda juga mencegah tar dari menimpa file saat membukanya di sistem target.

tar -c <source-dir> | ssh <name>@<host> 'tar -kxzf - -C <target-dir>' 
huembi
sumber
1
Itu membuat koneksi jarak jauh. Pertama tar adalah sumbernya, menyalurkannya ke koneksi ssh dan membukanya di sistem remote.
huembi
-1

scptidak menimpa file dan tidak ada saklar untuk menghentikannya, tetapi Anda dapat menyalin semuanya, melakukan scp dan kemudian menyalin kembali file yang ada. Contoh:

  1. Salin semua file yang ada

    mkdir original_files ; cp -r * original_files/
    
  2. Salin semuanya menggunakan scp

    scp -r user@server:dir/* ./
    
  3. Salin file asli di atas apa pun scp telah ditulis:

    cp -r original_files/* ./
    
A.Badger
sumber
3
Metode ini tidak membantu ketika Anda mencoba untuk menarik file dari remote dan mengambil di mana Anda tinggalkan. Yaitu jika seluruh tujuannya adalah untuk menghemat waktu.
Oliver Williams
-1

Cara lain untuk mencapai ini adalah dengan melakukan lspada folder tujuan:

Di folder tujuan jarak jauh:

ls | awk '{print "mv " $1 " ../copied_data/"}' > mv_copied_data
scp mv_copied_data [email protected]:/path/to/source/folder

Sumber:

cd /path/to/source/folder
chmod 777 mv_copied_data
./mv_copied_data

Di tempat tujuan:

scp -r [email protected]:/path/to/source/folder /path/to/destination/foldeer
gurjar sama
sumber
Tolong jangan lakukan ini. 1. Jangan menguraikan ls . 2. Jawabannya berbahaya jika ada nama file yang mengandung - >spasi baris baru atau karakter khusus lainnya. 3. Hard-code for-loop dalam skrip python. Membuat program saat runtime sulit dan rumit (bahkan ketika dilakukan oleh programmer profesional), untuk banyak alasan. Membuat skrip shell bahkan lebih buruk - ide yang buruk.
ignis