> Lembro que o ssh não aloca um psuedo-tty O que acontece? Enriqueceria a questão de entender qual é o problema.
Air
5
@ Air Não há um problema que eu estava tentando corrigir. Havia uma escolha de como o ssh é implementado que eu estava tentando entender. A pergunta é muito clara e a resposta de Andrew B trata bem da questão. A resposta pode ser resumida assim: correr ssh -tsempre é ruim porque pode fazer com que alguns comandos sejam quebrados de maneiras estranhas. Visto que a execução de um comando que precisa de um PTY sem um resulta em uma mensagem de erro clara de que você precisa de um terminal.
Chas. Owens
Respostas:
73
A principal diferença é o conceito de interatividade . É semelhante a executar comandos localmente dentro de um script, em vez de digitá-los você mesmo. É diferente, pois um comando remoto deve escolher um padrão e não interativo é mais seguro. (e geralmente mais honesto)
STDIN
Se um PTY for alocado, os aplicativos poderão detectar isso e saber que é seguro solicitar ao usuário informações adicionais sem interromper as coisas. Existem muitos programas que ignoram a etapa de solicitar entrada do usuário se não houver terminal presente, e isso é uma coisa boa. Isso faria com que os scripts travassem desnecessariamente caso contrário.
Sua entrada será enviada para o servidor remoto pela duração do comando. Isso inclui seqüências de controle. Enquanto uma Ctrl-cquebra normalmente faria com que um loop no comando ssh fosse interrompido imediatamente, suas seqüências de controle serão enviadas para o servidor remoto. Isso resulta em uma necessidade de "martelar" o pressionamento de tecla para garantir que ele chegue quando o controle sair do comando ssh, mas antes que o próximo comando ssh comece.
Eu recomendaria não usar ssh -tscripts autônomos, como crons. Um shell não interativo que solicita a um comando remoto que se comporte de maneira interativa está solicitando todos os tipos de problemas.
Você também pode testar a presença de um terminal em seus próprios scripts de shell. Para testar o STDIN com versões mais recentes do bash:
# fd 0 is STDIN
[ -t 0 ]; echo $?
STDOUT
Ao sshcriar um alias para ssh -t, você pode esperar um retorno de carro extra nas extremidades da sua linha. Pode não ser visível para você, mas está lá; aparecerá como ^Mquando canalizado cat -e. Em seguida, você deve fazer um esforço adicional para garantir que esse código de controle não seja atribuído às suas variáveis, principalmente se você deseja inserir essa saída em um banco de dados.
Também existe o risco de os programas assumirem que podem renderizar uma saída que não é amigável para o redirecionamento de arquivos. Normalmente, se você redirecionasse o STDOUT para um arquivo, o programa reconheceria que o seu STDOUT não é um terminal e omitiria qualquer código de cores. Se o redirecionamento STDOUT for da saída do cliente ssh e houver um PTY associado à extremidade remota do cliente, os programas remotos não poderão fazer essa distinção e você terminará com lixo de terminal no arquivo de saída. Redirecionar a saída para um arquivo na extremidade remota da conexão ainda deve funcionar conforme o esperado.
Aqui está o mesmo teste do bash do que antes, mas para STDOUT:
# fd 1 is STDOUT
[ -t 1 ]; echo $?
Embora seja possível contornar esses problemas, você inevitavelmente esquecerá o design de scripts. Todos nós fazemos em algum momento. Os membros da equipe também pode não perceber / lembre-se que este alias está no lugar, que por sua vez criar problemas para você quando eles escrever scripts que usam seus alias.
Aliasing sshpara ssh -té muito mais um caso onde você estará violando o princípio de projeto de menor surpresa ; as pessoas encontrarão problemas que não esperam e podem não entender o que está causando isso.
Um quase-se a impressão que eu tenho trabalhado em uma equipe que fez isso ...
Andrew B
No escopo coberto por esta resposta, é ótimo. Mas a questão tinha um escopo mais amplo, essencialmente querendo conhecer TODAS as diferenças (o que esperar). Informações adicionais: No nível do processo, -t PRIMEIRO alocará um tty e, em seguida, executará um shell (ao longo do caminho, fornecendo / etc / profile e ~ / .bash_profile) e, em seguida, executará o comando. Sem -t, o ssh INSTEAD fonte diferentes arquivos env (/etc/bash.bashrc, depois ~ / .bashrc) e então executa seu comando. Isto significa que você pode ver um comportamento muito diferente em cada um: mais curto $ PATH, talvez uma festa de erro 'unário' porque o var ENV você assumiu não está lá ...
Scott Prive
@Crossfit Abordamos o tópico de shells de login versus non nos comentários de outra resposta, mas não entramos em um colapso exaustivo das diferenças ambientais, porque o OP já havia considerado a pergunta respondida para suas necessidades particulares. Por favor, sinta-se à vontade para adicionar detalhes onde você vê espaço para fazê-lo, pois isso pode ajudar outras pessoas que se deparam com essas perguntas e respostas.
Andrew B
33
Caracteres de escape SSH e transferência de arquivos binários
Uma vantagem que não foi mencionada nas outras respostas é que, ao operar sem um pseudo-terminal , os caracteres de escape SSH , como não~C são suportados ; isso torna seguro para os programas transferir arquivos binários que podem conter essas seqüências.
Prova de conceito
Copie um arquivo binário usando um pseudo-terminal:
Isso é particularmente importante para programas como scpou rsyncque usam SSH para transferência de dados. Esta descrição detalhada de como o protocolo SCP funciona explica como o protocolo SCP consiste em uma mistura de mensagens de protocolo textuais e dados de arquivos binários.
O OpenSSH ajuda a proteger você de si mesmo
Vale ressaltar que, mesmo que o -tsinalizador seja usado, o sshcliente OpenSSH se recusará a alocar um pseudo-terminal se detectar que seu stdinfluxo não é um terminal:
$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb
Você ainda pode forçar o cliente OpenSSH a alocar um pseudo-terminal com -tt:
Bom, mas a saída é recuada /: Você sabe se pode devolver automaticamente o carro (como um unix)?
Boop
1
Pense em compatibilidade com versões anteriores.
Os dois modos principais do ssh são o logon interativo com um tty e o comando especificado sem um tty, porque esses eram os recursos exatos de rlogine rshrespectivamente. O ssh precisava fornecer um superconjunto de rlogin/ rshfeatures para ter sucesso como substituição.
Portanto, os padrões foram decididos antes do nascimento do ssh. Combinações como "Quero especificar um comando e obter um tty" precisavam ser acessadas com novas opções. Seja feliz que pelo menos nós tem essa opção agora, ao contrário de quando estávamos usando rsh. Não trocamos nenhum recurso útil para obter conexões criptografadas. Temos recursos de bônus!
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Isso permite que você obtenha uma espécie de "shell" para o servidor remoto. Para servidores que não concedem acesso ao shell, mas permitem SSH (ou seja, o Github é um exemplo conhecido para acesso ao SFTP), o uso desse sinalizador fará com que o servidor rejeite sua conexão.
O shell também possui todas as suas variáveis ambientais (como $PATH), portanto, a execução de scripts geralmente precisa de um tty para funcionar.
Isso não responde à pergunta. Eu já sei como alocar um pseudo-tty. Quero saber por que nem sempre devo alocar um.
Chas. Owens
11
@ Chas.Owens Porque, como indiquei na resposta, alguns servidores SSH não permitem acesso tty e a conexão será interrompida se você solicitar um do servidor.
C # de Nathan C
5
Acho que você pode estar confundindo parte da sua terminologia. Não é um shell simplesmente porque um PTY está associado a ele. Há geralmente três tipos de shell: non-interactive, interactive, e login. loginé uma característica adicional dos outros dois tipos de shell. As permutações desses três determinam quais arquivos são originados no logon, o que, por sua vez, influencia como o ambiente será inicializado. (variáveis, como você estava mencionando)
Andrew B
3
@AndrewB Você está certo ... Eu aprendi algo com essa pergunta também. :)
ssh -t
sempre é ruim porque pode fazer com que alguns comandos sejam quebrados de maneiras estranhas. Visto que a execução de um comando que precisa de um PTY sem um resulta em uma mensagem de erro clara de que você precisa de um terminal.Respostas:
A principal diferença é o conceito de interatividade . É semelhante a executar comandos localmente dentro de um script, em vez de digitá-los você mesmo. É diferente, pois um comando remoto deve escolher um padrão e não interativo é mais seguro. (e geralmente mais honesto)
STDIN
Ctrl-c
quebra normalmente faria com que um loop no comando ssh fosse interrompido imediatamente, suas seqüências de controle serão enviadas para o servidor remoto. Isso resulta em uma necessidade de "martelar" o pressionamento de tecla para garantir que ele chegue quando o controle sair do comando ssh, mas antes que o próximo comando ssh comece.Eu recomendaria não usar
ssh -t
scripts autônomos, como crons. Um shell não interativo que solicita a um comando remoto que se comporte de maneira interativa está solicitando todos os tipos de problemas.Você também pode testar a presença de um terminal em seus próprios scripts de shell. Para testar o STDIN com versões mais recentes do bash:
STDOUT
ssh
criar um alias parassh -t
, você pode esperar um retorno de carro extra nas extremidades da sua linha. Pode não ser visível para você, mas está lá; aparecerá como^M
quando canalizadocat -e
. Em seguida, você deve fazer um esforço adicional para garantir que esse código de controle não seja atribuído às suas variáveis, principalmente se você deseja inserir essa saída em um banco de dados.Aqui está o mesmo teste do bash do que antes, mas para STDOUT:
Embora seja possível contornar esses problemas, você inevitavelmente esquecerá o design de scripts. Todos nós fazemos em algum momento. Os membros da equipe também pode não perceber / lembre-se que este alias está no lugar, que por sua vez criar problemas para você quando eles escrever scripts que usam seus alias.
Aliasing
ssh
parassh -t
é muito mais um caso onde você estará violando o princípio de projeto de menor surpresa ; as pessoas encontrarão problemas que não esperam e podem não entender o que está causando isso.fonte
Caracteres de escape SSH e transferência de arquivos binários
Uma vantagem que não foi mencionada nas outras respostas é que, ao operar sem um pseudo-terminal , os caracteres de escape SSH , como não
~C
são suportados ; isso torna seguro para os programas transferir arquivos binários que podem conter essas seqüências.Prova de conceito
Copie um arquivo binário usando um pseudo-terminal:
Copie um arquivo binário sem usar um pseudo-terminal:
Os dois arquivos não são os mesmos:
O que foi copiado com um pseudo-terminal está corrompido:
enquanto o outro não é:
Transferindo arquivos pelo SSH
Isso é particularmente importante para programas como
scp
oursync
que usam SSH para transferência de dados. Esta descrição detalhada de como o protocolo SCP funciona explica como o protocolo SCP consiste em uma mistura de mensagens de protocolo textuais e dados de arquivos binários.O OpenSSH ajuda a proteger você de si mesmo
Vale ressaltar que, mesmo que o
-t
sinalizador seja usado, ossh
cliente OpenSSH se recusará a alocar um pseudo-terminal se detectar que seustdin
fluxo não é um terminal:Você ainda pode forçar o cliente OpenSSH a alocar um pseudo-terminal com
-tt
:Em ambos os casos, (sensatamente) não se importa se é
stdout
oustderr
é redirecionado:fonte
No host remoto, temos a ver com esta configuração:
Sem sudo
E com sudo
Com o sudo, obtemos o retorno de carro extra
A solução é desativar a linha nova de conversão em linha de retorno de carro com
stty -onlcr
fonte
Pense em compatibilidade com versões anteriores.
Os dois modos principais do ssh são o logon interativo com um tty e o comando especificado sem um tty, porque esses eram os recursos exatos de
rlogin
ersh
respectivamente. O ssh precisava fornecer um superconjunto derlogin
/rsh
features para ter sucesso como substituição.Portanto, os padrões foram decididos antes do nascimento do ssh. Combinações como "Quero especificar um comando e obter um tty" precisavam ser acessadas com novas opções. Seja feliz que pelo menos nós tem essa opção agora, ao contrário de quando estávamos usando
rsh
. Não trocamos nenhum recurso útil para obter conexões criptografadas. Temos recursos de bônus!fonte
De
man ssh
:Isso permite que você obtenha uma espécie de "shell" para o servidor remoto. Para servidores que não concedem acesso ao shell, mas permitem SSH (ou seja, o Github é um exemplo conhecido para acesso ao SFTP), o uso desse sinalizador fará com que o servidor rejeite sua conexão.
O shell também possui todas as suas variáveis ambientais (como
$PATH
), portanto, a execução de scripts geralmente precisa de um tty para funcionar.fonte
non-interactive
,interactive
, elogin
.login
é uma característica adicional dos outros dois tipos de shell. As permutações desses três determinam quais arquivos são originados no logon, o que, por sua vez, influencia como o ambiente será inicializado. (variáveis, como você estava mencionando)