Rsync tampaknya tidak kompatibel dengan .bashrc (menyebabkan "apakah shell Anda bersih?")

16

Ternyata rsync tidak dapat bekerja dengan server jauh yang memiliki file .bashrc?

Di klien lokal saya dapatkan ketika menjalankan rsync:

protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(180) [sender=3.0.7]

Seperti yang disarankan di sini menghapus .bashrc di server memecahkan masalah. Bagaimana mengatasinya tanpa menghapus file .bashrc (sementara)?

Komputis
sumber
1
Periksa apakah ssh diaktifkan untuk akun itu.
Lamy
Jawaban di bawah ini kemungkinan besar salah. Saya baru-baru ini mulai mendapatkan kesalahan ini setelah upgrade Ubuntu rutin, meskipun tidak ada yang berubah pada file .bashrc saya.
Cerin
Tidak - jika menghapus file .bashrc memperbaikinya (seperti yang dinyatakan dalam pertanyaan ini), maka masalahnya adalah output dari .bashrc. Peningkatan tentu saja dapat menyebabkan ketidakcocokan protokol yang sebenarnya, yang merupakan masalah yang sama sekali berbeda.
Randall

Jawaban:

21

Anda dapat mengalami masalah jika .bashrcserver jauh mengeluarkan sesuatu ke terminal. Rsync mungkin tidak mengharapkan itu dan mungkin memiliki masalah sebagai hasilnya.

Anda dapat memperbaikinya dengan menghapus perintah apa pun di .bashrcteks keluaran itu, atau dengan memipakan keluaran apa pun ke / dev / null.

Greg Hewgill
sumber
3
Jadi bagaimana cara mem-pipe output ke / dev / null jika saya hanya dapat memodifikasi file pada klien?
Computist
1
Saya kira Anda bisa sebagai administrator sistem Anda untuk bantuan. Anda juga dapat memodifikasi file di server dengan cara lain, seperti FTP atau scp.
Greg Hewgill
Ya file .bashrc saya berisi echo "*** Starting ROOT Shell ***" dan echo "(Silakan gunakan sudo alih-alih shell root bila memungkinkan!)". Menghapus gema itu memperbaiki masalah.
Kentgrav
1
Dari halaman manual rsync: "versi protokol tidak cocok - apakah shell Anda bersih?" Pesan ini biasanya disebabkan oleh skrip startup atau fasilitas shell jarak jauh yang menghasilkan sampah yang tidak diinginkan pada stream yang digunakan rsync untuk pengangkutannya. Cara untuk mendiagnosis masalah ini adalah dengan menjalankan remote shell Anda seperti ini: ssh remotehost / bin / true> out.dat lalu lihat file out.dat. Jika semuanya bekerja dengan benar maka out.dat harus berupa file dengan panjang nol.
Kentgrav
8

.Bashrc benar-benar bukan tempat yang tepat untuk menghasilkan output, karena menyebabkan masalah semacam ini. Banyak orang lolos begitu saja, sampai mereka mencoba menjalankan rsync :-)

Setiap output yang diinginkan (dan logika serta perintah yang terkait) harus dipindahkan ke .bash_profile Anda (lihat, mis., Pertanyaan Server Fault ".profile vs. .bash_profile vs. .bashrc" untuk diskusi lebih lanjut tentang perbedaan antara file-file).

Dengan begitu, Anda tidak perlu berkorban untuk mendapatkan output ketika Anda login, atau berurusan dengan membuat perubahan sementara pada .bashrc Anda saat Anda ingin menggunakan rsync.

Randall
sumber
6

Saya selalu memiliki file .bashrc pada akun pengguna saya dan tidak pernah memiliki masalah ini sampai saya mencoba hari ini untuk rsync sesuatu ke server saya menggunakan akun root. Pos Anda membantu saya menemukan solusinya:

file $ user / .bashrc saya selalu dimulai dengan bagian berikut untuk mencegah masalah seperti ini. Saya menyalinnya ke root .bashrc dan rsync'ing sekarang berfungsi seperti mantra!

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

HTH, karsten

karsten
sumber
Ini biasanya tidak berhasil rsync, karena untuk alasan apa pun diklasifikasikan sebagai "shell interaktif". Tapi itu adalah baris yang baik untuk ditambahkan, karena mungkin mengacaukan shell non-interaktif jika tidak ada output
Michael Schubert
Saya pikir ini adalah solusi terbaik untuk pertanyaan itu. Jawaban terima "menghapus perintah apa pun di .bashrc yang menampilkan teks" tidak praktis.
Qinsi
4

Untuk alasan kompleks rsync / scp / sftp menjalankan .bashrc saat menghubungkan ke host lain. Anda harus memiliki salah satu dari perintah ini di bagian atas .bashrc Anda :

antara

[[ $- != *i* ]] && return

atau

[ -z "$PS1" ] && return

Salah satu dari perintah di atas hanya akan memungkinkan pelaksanaan sisa perintah .bashrc untuk sesi interaktif . Sejauh yang saya tahu Anda tidak membutuhkannya untuk jenis sesi lain (dan memang saya telah melihat bashrc default dari Arch dan Debian menggunakan teknik ini di bashrc mereka).

Namun jika Anda ingin menjadi paranoid ekstra tentang membiarkan perintah bashrc Anda berjalan bahkan untuk sesi non-interaktif, Anda setidaknya harus membungkus perintah-perintah bashrc Anda yang menghasilkan output seperti ini ( referensi ) sehingga hanya berjalan dalam sesi interaktif:

if shopt -q login_shell; then
    # this is an interactive session, we _can_ display output
    ...code that produces output goes here...
fi

Perhatikan bahwa orang lain menyarankan untuk memindahkan perintah yang menampilkan teks ke bash_profile Anda, tetapi saya ragu apakah ini selalu baik (untuk alasan yang dijelaskan di sini )

ndemou
sumber