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 .bashrc
o 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.bashrc
contivesse 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). scp
usaentrada 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ê ssh
entre com êxito em um shell de login interativo, você pode fazer isso, abrir .bashrc
no 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, .bashrc
os arquivos dos usuários e de todo o sistema /etc/bash.bashrc
geralmente começam com essas verificações.
O arquivo padrão .bashrc
no Ubuntu, copiado de /etc/skel
quando 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 .bashrc
arquivos e que atualmente é usado no /etc/bash.bashrc
arquivo 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 .bashrc
arquivo 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 .bashrc
ou /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 scp
sessão e impedirá scp
a 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. bash
executa comandos de ~/.bashrc
e /etc/bash.basrhc
quando:
- o shell é interativo,ou
- outro script de inicialização como
/etc/profile
ou~/.profile
fontes,mas também - quando
bash
nã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 bash
toma 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 bash
ea versão desshd
que está sendo usado.
Nos sistemas Debian e Ubuntu atuais, quando bash
executado como um shell não interativo e sem login, ele verifica se a SSH_CLIENT
variá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 SHLVL
variável de ambiente é definida com um valor menor que 2 - indicando que é a sessãoinicialshell-- bash
executa os comandos em /etc/bash.bashrc
e ~/.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_files
funçã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-script
bash
-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 bash
como 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 ssh
em geral, scp
faz 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/passwd
ou na saída do usuário getent passwd
(que também é definido como o valor da $SHELL
variá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 bash
no 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 .bashrc
serão /etc/bash.bashrc
executados por esse shell. Se eles produzem resultados – intencionalmente ou não – entãoscp
não será possível copiar arquivos.