O problema e como resolvê-lo

O problema e como resolvê-lo

Tendo um problema estranho de 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

A senha funciona bem, mas fica com aquela coisa estranha de \033H. E o arquivo não é transferido. Alguém tem alguma ideia?

Responder1

A solução para isso normalmente é simples. Normalmente você pode inspecionar .bashrc, encontrar a linha ou algumas linhas próximas ao topo que estão causando o problema e movê-las ou excluí-las. A parte difícil é convencer as pessoas de que esse problema é realmente real. Os detalhes seguem, mas se você quiser apenasconsertareste problema, então você só precisará usar esta primeira seção mais curta.

O problema e como resolvê-lo

Isso acontece quando .bashrco diretório inicial do usuário na máquina remota contém comandos que produzem saídae que rodam mesmo em shells não interativos.Menos comumente, isso também aconteceria se todo o sistema /etc/bash.bashrccontivesse tais comandos. A saída específica varia dependendo do que a está produzindo. Mas a combinação de receber resultados inesperados enãoter qualquer transferência bem-sucedida ou até mesmo começarmuitoaponta fortemente para essa causa (especialmente quando o servidor é um sistema Debian ou Ubuntu). scpusaentrada e saída padrãopara enviar e receber dados e, se dados não relacionados forem transmitidos por meio deles, ele não poderá transferir arquivos.

Se você está pensando,"Isso é impossível, .bashrcé apenas para shells interativos!"ou de outra forma estiver interessado em uma explicação detalhada de por que isso ocorre, consulte a segunda seção abaixo.

Este problema não interrompe o SSHing normal. Portanto, supondo que o sistema esteja configurado para permitir que você sshentre com êxito em um shell de login interativo, você pode fazer isso, abrir .bashrcno diretório inicial do usuário remoto e remover ou comentar (com #) o comando ou comandos ofensivos, se não o fizer. não preciso deles. Ou, se você precisar deles, mova-os para baixo de outro comando que aborta quando o shell não é interativo. Esse comando já pode estar presente.No Ubuntu e em algumas outras distros, .bashrcos arquivos dos usuários e de todo o sistema /etc/bash.bashrcgeralmente começam com essas verificações.

O arquivo padrão .bashrcno Ubuntu, copiado de /etc/skelquando uma conta de usuário é criada, contém este código para verificar se o shell em execução é interativo e para evitar que quaisquer comandos adicionais no arquivo sejam executados, se fornão:

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

Outro método comum, que algumas pessoas usam em seus .bashrcarquivos e que atualmente é usado no /etc/bash.bashrcarquivo de todo o sistema para todos os usuários, é:

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

Se os arquivos foram substituídos ou modificados em relação ao padrão, você poderá ver qualquer uma das técnicas sendo usadas em qualquer arquivo. Existem outras maneiras possíveis de verificar a operação interativa, mas elas são incomuns. Se o usuário escreveu seu próprio .bashrcarquivo do zero ou o trouxe de outro sistema operacional que não seja Debian, Ubuntu ou outro derivado do Debian, então é provável que ele não tenha esse código. Mas se precisar, você ainda pode adicioná-lo.

Qualquer comando que produza saída e apareça em .bashrcou /etc/bash.bashrc, a menos que apareçadepoiscódigo como o mostrado acima fará com que dados inesperados sejam enviados no início de uma scpsessão e impedirá scpa transferência de arquivos.

Se você editou recentemente um desses arquivos adicionando um comando ao topo, será fácil descobrir a alteração específica que causou o problema. Mesmo que não, a descrição acima pode fornecer informações suficientes.

Porém, recomendo que você edite sua pergunta com todos os detalhes, incluindo o conteúdo desses arquivos, independentemente de conseguir ou não resolver o problema com base na explicação acima. Lembre-se dissoestes são os arquivos no servidor remoto, não na máquina cliente. Isso deve ajudar outras pessoas que encontrem sua dúvida a compreender o problema, além de possibilitar conselhos mais específicos, se necessário.

Acredito que a probabilidade de seu problema ser causado por algo totalmente diferente seja muito baixa, mas de qualquer forma, as informações adicionadas devem permitir ter certeza.Outras pessoasdo que o autor desta pergunta, que tem problemas semelhantes e precisa de ajuda para resolvê-los, é claronãoedite esta pergunta, mas deve postar sua própria pergunta.


Por que o problema ocorre

As pessoas costumam dizer que isso .bashrcé apenas para shells interativos, mas isso é um equívoco ou, na melhor das hipóteses, uma simplificação severa. bashexecuta comandos de ~/.bashrce /etc/bash.basrhcquando:

  1. o shell é interativo,ou
  2. outro script de inicialização como /etc/profileou~/.profile fontes,mas também
  3. quando bashnão está sendo executado de forma interativa nem como um shell de login, mas determina que provavelmente está sendo executado como o shell inicialem uma conexão remota.

O que bashtoma como evidência suficiente que se trata de um shell remoto - e, portanto, se, na prática, esse efeito ocorre ou não com SSH - depende principalmente decomo foi compilado, o que varia entre os sistemas operacionaise, secundariamente, na versão de bashea versão desshdque está sendo usado.

Nos sistemas Debian e Ubuntu atuais, quando bashexecutado como um shell não interativo e sem login, ele verifica se a SSH_CLIENTvariável de ambiente está definida e não vazia. (Ele verifica outras coisas também, mas para SSH nos sistemas Ubuntu atuais, eles não revelam nada.) Nesse caso, a SHLVLvariável de ambiente é definida com um valor menor que 2 - indicando que é a sessãoinicialshell-- bashexecuta os comandos em /etc/bash.bashrce ~/.bashrc.

Para verificar isso rapidamente sem modificar os arquivos de configuração, os leitores podempasse essas variáveis ​​manualmente para bash -c ''o ambiente de e rastreie o que lê, ou examine a run_startup_filesfunção emshell.c(que começa na linha 1022 nessa versão).

Um shell não interativo e sem login bashé o que você obtém quando executa um script com bash, seja executando-o após definir as permissões necessárias e conceder-lheuma linha hashbang apropriadaou executando explicitamente. É também o que você obtém quando executa uma linha única com a opção, como:bash your-scriptbash-c

bash -c 'echo hello world'

Como seria de esperar, a casca que você obtém quandoConecte-sevia SSH para umsessão interativaé um shell de login interativo. Isso é o que você obtém ao executar um comando como este (supondo que seja bem-sucedido):

ssh [email protected]

Mas é aqui que entra a parte não intuitiva: a casca que você obtém quandoConecte-sevia SSH para umnão interativosessão não é interativasem loginconcha. Isso é o que você obtém ao executar um único comando via SSH:

ssh [email protected] command args...

Ou seja, a execução de um único comando via SSH é executada bashcomo o mesmo tipo de shell - um shell não interativo e sem login - como quando você executa um único comando localmente (ou em uma sessão remota já estabelecida) usando bash -c.

Como sshem geral, scpfaz com que um shell seja executado na máquina remota como usuário remoto. Isso ainda é o que eles configuraram como shell, ou seja, o shell listado na entrada /etc/passwdou na saída do usuário getent passwd(que também é definido como o valor da $SHELLvariável de ambiente quando eles estão logados). A menos que eles tenham mudado executando chsh, este é o shell de usuário padrão, que no Ubuntu é bash.

É por isso que comandos comoesseexecute também um shell não interativo sem login bashno servidor remoto:

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

A menos que sejam protegidos por código para parar se o shell não for interativo, os comandos .bashrcserão /etc/bash.bashrcexecutados por esse shell. Se eles produzem resultados – intencionalmente ou não – entãoscpnão será possível copiar arquivos.

informação relacionada