El problema y cómo solucionarlo

El problema y cómo solucionarlo

Tener un problema extraño con scp:

$ scp [email protected]:~/test.txt ./
Password:
\033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H

La contraseña funciona bien, pero aparece esa cosa extraña \033H. Y el archivo no se transfiere. ¿Alguien tiene alguna idea?

Respuesta1

La solución para esto suele ser sencilla. Por lo general, puede inspeccionar .bashrc, encontrar la línea o un par de líneas cerca de la parte superior que están causando el problema y moverlas o eliminarlas. La parte difícil es convencer a la gente de que este problema es real. A continuación se detallan los detalles, pero si solo quieresarreglareste problema, entonces sólo necesitarás usar esta primera sección más corta.

El problema y cómo solucionarlo

Esto sucede cuando .bashrcel directorio de inicio del usuario en la máquina remota contiene comandos que producen resultados.y que se ejecutan incluso en shells no interactivos.Con menos frecuencia, también sucedería si todo el sistema /etc/bash.bashrccontiene dichos comandos. La producción específica varía según lo que la produce. Pero la combinación de recibir resultados inesperados ynotener cualquier transferencia exitosa o incluso comenzarmuyapunta fuertemente hacia esa causa (especialmente cuando el servidor es un sistema Debian o Ubuntu). scpusosentrada y salida estándarpara enviar y recibir datos, y si se transmiten datos no relacionados a través de ellos, entonces no puede transferir archivos.

Si estás pensando,"¡Eso es imposible, .bashrces sólo para shells interactivos!"o está interesado en una explicación detallada de por qué ocurre esto, consulte la segunda sección a continuación.

Este problema no interrumpe el SSH normal. Entonces, suponiendo que el sistema esté configurado para permitirle ingresar sshexitosamente a un shell de inicio de sesión interactivo, puede hacerlo, abrirlo .bashrcen el directorio de inicio del usuario remoto y eliminar o comentar (con #) el comando o comandos infractores, si no lo hace. No los necesito. O si los necesita, muévalos debajo de otro comando que cancele cuando el shell no sea interactivo. Es posible que dicho comando ya esté presente.En Ubuntu y algunas otras distribuciones, .bashrclos archivos de los usuarios y todo el sistema /etc/bash.bashrcgeneralmente comienzan con este tipo de comprobaciones.

El archivo predeterminado .bashrcen Ubuntu, copiado /etc/skelcuando se crea una cuenta de usuario, contiene este código para verificar si el shell en ejecución es interactivo y para evitar que se ejecuten más comandos en el archivo si es así.no:

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

Otro método común, que algunas personas usan en sus .bashrcarchivos y que actualmente se usa en el /etc/bash.bashrcarchivo de todo el sistema para todos los usuarios, es:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Si los archivos han sido reemplazados o modificados con respecto a los valores predeterminados, es posible que vea el uso de cualquiera de las técnicas en cualquiera de los archivos. Hay otras formas posibles de comprobar el funcionamiento interactivo, pero son poco comunes. Si el usuario escribió su propio .bashrcarchivo desde cero o lo trajo de otro sistema operativo que no sea Debian, Ubuntu u otro derivado de Debian, entonces es probable que no tenga dicho código en absoluto. Pero si lo necesitas, aún puedes agregarlo.

Cualquier comando que produzca resultados y aparezca en .bashrco /etc/bash.bashrc, a menos que aparezcadespuésUn código como el que se muestra arriba provocará que se envíen datos inesperados al inicio de una scpsesión y evitará scpque se puedan transferir archivos.

Si usted mismo editó recientemente uno de estos archivos agregando un comando en la parte superior, entonces debería resultarle fácil descubrir el cambio específico que causó el problema. Incluso si no, la descripción anterior puede brindarle suficiente información.

Sin embargo, le recomiendo que edite su pregunta con todos los detalles, incluido el contenido de esos archivos, independientemente de si puede resolver el problema según la explicación anterior. Recuerda esoestos son los archivos en el servidor remoto, no en la máquina cliente. Esto debería ayudar a otras personas que encuentren su pregunta a comprender el problema, además de permitir que se brinden consejos más específicos, si es necesario.

Creo que la probabilidad de que su problema sea causado por algo completamente diferente es muy baja, pero de cualquier manera, la información agregada debería permitir saberlo con certeza.Otra genteque el autor de esta pregunta que tiene problemas similares y necesita ayuda para resolverlos, por supuesto, deberíanoedite esta pregunta, pero debería publicar su propia pregunta.


Por qué ocurre el problema

La gente suele decir que esto .bashrces sólo para shells interactivos, pero es un error o, en el mejor de los casos, una simplificación excesiva. bashejecuta comandos desde ~/.bashrcy /etc/bash.basrhccuando:

  1. el caparazón es interactivo,o
  2. otro script de inicio como /etc/profileo~/.profile lo obtiene,pero también
  3. cuando bashno se ejecuta de forma interactiva ni como shell de inicio de sesión, pero determina que probablemente se esté ejecutando como shell inicialen una conexión remota.

Qué bashtoma como evidencia suficiente que es un shell remoto (y por lo tanto, si en la práctica este efecto ocurre o no con SSH) depende principalmente decómo se compiló, que varía según el sistema operativo, y en segundo lugar en la versión de bashyla versión desshdque se está utilizando.

En los sistemas Debian y Ubuntu actuales, cuando bashse ejecuta como un shell no interactivo sin inicio de sesión, verifica si la SSH_CLIENTvariable de entorno está configurada y no está vacía. (También verifica otras cosas, pero para SSH en los sistemas Ubuntu actuales, no revelan nada). Si es así, y la SHLVLvariable de entorno se establece en un valor menor que 2, lo que indica que es la sesióninicialshell: bashejecuta los comandos en /etc/bash.bashrcy ~/.bashrc.

Para verificar esto rápidamente sin modificar los archivos de configuración, los lectores puedenpasar esas variables manualmente al bash -c ''entorno de y rastrear lo que lee, o examinar la run_startup_filesfunción enshell.c(que comienza en la línea 1022 en esa versión).

Un shell no interactivo sin inicio de sesión bashes lo que obtienes cuando ejecutas un script con bash, ya sea ejecutándolo después de configurar los permisos necesarios y otorgarleuna línea hashbang apropiadao ejecutándolo explícitamente. También es lo que obtienes cuando ejecutas una frase con la opción, como por ejemplo:bash your-scriptbash-c

bash -c 'echo hello world'

Como era de esperar, el caparazón que obtienes cuandoaccesovía SSH para unsesión interactivaes un shell de inicio de sesión interactivo. Eso es lo que obtienes cuando ejecutas un comando como este (suponiendo que tenga éxito):

ssh [email protected]

Pero aquí es donde entra en juego la parte no intuitiva: el caparazón que obtienes cuandoaccesovía SSH para unno interactivoLa sesión no es interactiva.sin iniciar sesióncaparazón. Eso es lo que obtienes al ejecutar un único comando a través de SSH:

ssh [email protected] command args...

Es decir, ejecutar un solo comando a través de SSH se ejecuta bashcomo el mismo tipo de shell (un shell no interactivo y sin inicio de sesión) que cuando ejecuta un solo comando localmente (o dentro de una sesión remota ya establecida) usando bash -c.

Como sshen general, scphace que se ejecute un shell en la máquina remota como usuario remoto. Esto sigue siendo lo que hayan configurado como su shell, es decir, el shell que figura en la entrada /etc/passwdo salida del usuario getent passwd(que también se establece como el valor de la $SHELLvariable de entorno cuando inician sesión). A menos que lo hayan cambiado ejecutando chsh, este es el shell de usuario predeterminado, que en Ubuntu es bash.

Por eso comandos comoesteEjecute también un shell no interactivo sin inicio de sesión bashen el servidor remoto:

scp [email protected]:~/test.txt ./

A menos que estén protegidos por un código para detenerse si el shell no es interactivo, los comandos en dicho shell .bashrco /etc/bash.bashrcson ejecutados por dicho shell. Si producen resultados, intencionalmente o no, entoncesscpno podrá copiar archivos.

información relacionada