Rsync parece incompatible con .bashrc (causa "¿está limpio su shell?")

16

Resulta que rsync no puede funcionar con un servidor remoto que tiene un archivo .bashrc?

En el cliente local que obtuve cuando ejecuté 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]

Como se sugiere aquí, eliminar el .bashrc en el servidor resolvió el problema. ¿Cómo resolverlo sin eliminar el archivo .bashrc (temporalmente)?

Computista
fuente
1
Compruebe si ssh está habilitado para esa cuenta.
Lamy
Las respuestas a continuación son probablemente incorrectas. Recientemente comencé a recibir este error después de una actualización rutinaria de Ubuntu, aunque nada cambió en mis archivos .bashrc.
Cerin
No, si la eliminación del archivo .bashrc lo soluciona (como se indicó en esta pregunta), el problema se genera desde el .bashrc. Una actualización ciertamente podría introducir una incompatibilidad de protocolo real, que es un problema completamente diferente.
Randall el

Respuestas:

21

Puede tener problemas si el .bashrcservidor remoto emite algo al terminal. Rsync puede no esperar eso y puede tener problemas como resultado.

Puede solucionar esto eliminando cualquier comando en .bashrcese texto de salida, o canalizando cualquier salida a / dev / null.

Greg Hewgill
fuente
3
Entonces, ¿cómo canalizar cualquier salida a / dev / null si solo puedo modificar archivos en el cliente?
Computista
1
Supongo que podría como administrador de su sistema para obtener ayuda. También puede modificar archivos en el servidor de otra manera, como FTP o scp.
Greg Hewgill el
Sí, mi archivo .bashrc contenía un eco "*** Iniciando ROOT Shell ***" y echo "(¡Utilice sudo en lugar de un shell raíz siempre que sea posible!"). Eliminar esos ecos solucionó el problema.
Kentgrav
1
Desde la página de manual de rsync: "la versión del protocolo no coincide - ¿está limpio su shell?" Este mensaje generalmente es causado por sus scripts de inicio o instalación remota de shell que produce basura no deseada en la secuencia que rsync está utilizando para su transporte. La forma de diagnosticar este problema es ejecutar su shell remoto de esta manera: ssh remotehost / bin / true> out.dat y luego mirar el archivo out.dat. Si todo funciona correctamente, out.dat debería ser un archivo de longitud cero.
Kentgrav
8

El .bashrc realmente no es el lugar correcto para generar resultados, ya que causa este tipo de problema. Sin embargo, mucha gente se sale con la suya hasta que intentan ejecutar rsync :-)

Cualquier salida deseada (y la lógica y los comandos asociados) se deben mover a su .bash_profile (consulte, por ejemplo, la pregunta de error del servidor ".profile vs. .bash_profile vs. .bashrc" para obtener más información sobre las diferencias entre los archivos).

De esa manera, no tendrá que sacrificar la obtención de la salida cuando inicie sesión, ni tratar de hacer cambios temporales en su .bashrc cuando quiera usar rsync.

Randall
fuente
6

Siempre tuve archivos .bashrc en mis cuentas de usuario y nunca tuve este problema hasta que intenté hoy sincronizar algo con mi servidor usando la cuenta raíz. Tu publicación me ayudó a encontrar la solución:

mis archivos $ user / .bashrc siempre comienzan con la siguiente sección para evitar este tipo de problema. ¡Lo repliqué en .bashrc de raíz y rsync'ing ahora funciona de maravilla!

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

HTH, karsten

karsten
fuente
Por lo general, esto no funciona rsyncporque, por cualquier motivo, se clasifica como "shell interactivo". Pero es una buena línea para agregar de todos modos, ya que de lo contrario podría arruinar shells no interactivos si hay alguna salida.
Michael Schubert
Creo que esta es la mejor solución a la pregunta. La respuesta de aceptación "eliminar cualquier comando en el .bashrc que genere texto" no es práctica.
Qinsi
4

Por razones complejas, rsync / scp / sftp ejecuta .bashrc cuando se conecta a otro host. Debe tener cualquiera de estos comandos en la parte superior de su .bashrc :

ya sea

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

o

[ -z "$PS1" ] && return

Cualquiera de los comandos anteriores solo permitirá la ejecución del resto de comandos .bashrc para sesiones interactivas . Hasta donde sé, no los necesita para ningún otro tipo de sesión (y de hecho, he visto bashrc predeterminado de Arch y Debian usando esta técnica en su bashrc).

Sin embargo, si desea ser más paranoico acerca de permitir que sus comandos bashrc se ejecuten incluso para sesiones no interactivas, al menos debe ajustar los comandos de su bashrc que producen resultados como este ( referencia ) para que solo se ejecuten en sesiones interactivas:

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

Tenga en cuenta que otros sugieren mover comandos que envían texto a su bash_profile, pero tengo mis dudas sobre si esto siempre es bueno (por las razones explicadas aquí )

ndemou
fuente