rsync: lewati file yang saya tidak punya izinnya

16

Saya menggunakan rsync -rlptDuntuk menyalin direktori dari pengguna lain. Ada beberapa file (saya tidak punya cara untuk mengetahui ini di muka) yang saya tidak punya izin untuk menyalin. Apakah ada cara agar rsync mengabaikan ini. Masalahnya adalah jika rsync mengembalikan non-nol, skrip bash -x saya akan keluar.

JeffCharter
sumber
Rsync telah mendokumentasikan nilai keluar dengan baik. Anda seharusnya tidak memperlakukan mereka semua sebagai kegagalan jika situasi Anda tidak meminta itu gagal.
jordanm
@jordanm Tapi tidak ada kode kesalahan yang cukup spesifik untuk menunjukkan kesalahan ini saja.
Gilles 'SO- stop being evil'

Jawaban:

7

Rsync tidak memiliki opsi untuk ini. Saya melihat dua solusi. Salah satunya adalah untuk mem-parsing pesan kesalahan rsync; ini tidak terlalu kuat. Yang lainnya adalah membuat daftar file yang tidak dapat dibaca untuk difilter.

cd /source/directory
exclude_file=$(mktemp)
find . ! -readable -o -type d ! -executable |
  sed -e 's:^\./:/:' -e 's:[?*\\[]:\\1:g' >>"$exclude_file"
rsync -rlptD --exclude-from="$exclude_file" . /target/directory
rm "$exclude_file"

Jika Anda findtidak memiliki -readabledan -executable, ganti dengan -permarahan yang sesuai .

Ini mengasumsikan bahwa tidak ada file yang tidak dapat dibaca yang namanya berisi baris baru. Jika Anda perlu mengatasinya, Anda harus membuat daftar file yang dibatasi nol seperti ini, dan meneruskan -0opsi ke rsync:

find . \( ! -readable -o -type d ! -executable \) -print0 |
  perl -0000 -pe 's:\A\./:/:' -e 's:[?*\\[]:$1:g' >>"$exclude_file"
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Ini mungkin taruhan terbaiknya. Mudah-mudahan, dia hanya perlu menjalankan ini sekali, karena harus stat()setiap file dua kali (sekali via rsync dan sekali via find) akan sangat buruk.
jordanm
@Gilles sepertinya ini berfungsi, kecuali untuk file tersembunyi. Saya mengasumsikan strategi yang sama akan bekerja dengan beberapa penyesuaian kecil. Saya tidak terbiasa dengan \! (seru tanda seru) bisakah Anda menjelaskannya?
JeffCharter
1
@JeffC \!mengutip !operator untuk melindunginya dari ekspansi shell. Backslash sebenarnya tidak diperlukan di sini karena tidak ada shell yang mengembang !ketika diikuti oleh spasi, tetapi tidak sakit. Apa yang salah dengan file tersembunyi?
Gilles 'SO- stop being evil'
3

Saya membuat solusi sederhana untuk situasi khusus ini:

rsync --args || $(case "$?" in 0|23) exit 0 ;; *) exit $?; esac)

Ini kembali 0jika kode yang dikembalikan adalah 0 atau 23, dan mengembalikan kode keluar dalam semua kasus lainnya.

Penting untuk dicatat, bahwa ini akan mengabaikan semua Partial transfer due to errorkesalahan, bukan hanya izin , karena akan menangkap semua yang keluar dari kode 23. Untuk informasi lebih lanjut tentang kode status rsync silakan lihat tautan ini .

Gus
sumber