`ssh <host>` é um shell de login, mas `ssh <host> <comando>` não é?


12

Percebi que quando executo um comando diretamente em um host SSH usando a ssh <host> <command>sintaxe, vejo a saída de, .bashrcmas não a saída de .bash_profile(ou .profile).

Por exemplo, se eu colocar o seguinte comando na parte superior dos dois arquivos,

echo ${BASH_SOURCE[0]}

e manualmente fonte .bash_profile(que fontes .bashrcpor sua vez), vou ver

$ . .bash_profile
.bash_profile
.bashrc

Essa é a mesma saída que eu vejo se fizer login neste computador remotamente via SSH, usando o ssh <host>formulário do comando. (E se eu guardar .bash_profiletemporariamente em outro lugar temporariamente, nenhuma dessas linhas será reproduzida.)

No entanto, se eu executar um comando diretamente na máquina remota com o ssh <host> <command>formato de ssh, a saída será assim:

$ ssh <host> echo foo
/home/rlue/.bashrc
foo

Meu entendimento é que a diferença entre .bash_profilee .bashrcé que o primeiro é para shells de login, enquanto o último é para shells interativos e sem login .

Concluí o seguinte:

  1. ssh <host>apenas fontes .bash_profile, enquanto
  2. ssh <host> <command>apenas fontes .bashrc, o que significa
  3. o primeiro é um shell de login e o segundo não.

Essas conclusões estão corretas? Por que é ssh <host> <command>tratado como um shell interativo e sem login? O SSH ainda não está efetuando login na máquina remota para executar o comando?


saída de .bashrc? Esse arquivo não deve produzir nenhuma saída. Qualquer saída de .bashrcpode quebrar todas as ferramentas usando ssh como transporte.
— kasperd

Justo. Nesse caso, algumas linhas .bashrcestavam lançando um erro, enquanto linhas semelhantes .bash_profilenão estavam. Aproveitei a oportunidade para investigar a discrepância antes de consertar as linhas ofensivas.
— Ryan Lue

Respostas:


12

O OpenSSH (provavelmente o que você está executando) decide se deve ou não criar um shell de login, e só o faz se você não estiver executando um comando específico. De man ssh:

 If command is specified, it is executed on the remote host instead of a
 login shell.

Portanto, é uma opção de implementação para o servidor ssh, se ele deseja criar um shell de login ou não, e se você der um comando para executar, isso não acontece.

Embora sshfaça um login, se você estiver executando um comando e sair, é muito mais parecido com a criação de um shell apenas para executar esse comando do que com um ambiente de login. Parece, dado que, as pessoas que escreviam o OpenSSH decidiram tratá-lo como esse tipo de tarefa.

Eles criam um shell não interativo e sem login para executar o comando, porque esse é o espírito de executar um comando em outro contexto / shell. Normalmente, porém, shells não interativos não seriam automaticamente fonte do ~/.bashrcque está acontecendo claramente aqui. bashestá realmente tentando nos ajudar aqui. Dos documentos

Chamado pelo daemon de shell remoto

O Bash tenta determinar quando está sendo executado com sua entrada padrão conectada a uma conexão de rede, como quando executada pelo daemon de shell remoto, geralmente rshd, ou pelo daemon de shell seguro sshd. Se o Bash determinar que está sendo executado dessa maneira, ele lê e executa comandos de ~ / .bashrc, se esse arquivo existe e é legível. Isso não será feito se invocado como sh. A opção --norc pode ser usada para inibir esse comportamento, e a opção --rcfile pode ser usada para forçar a leitura de outro arquivo, mas nem o rshd nem o sshd geralmente invocam o shell com essas opções ou permitem que sejam especificados.


"... é executado no host remoto em vez de um shell de login." Eu não entendo essa dicotomia. O comando é executado no host remoto em vez de em um shell de logon ou o comando é executado no host remoto, em vez de um shell de logon sendo executado lá? Se o primeiro, como é / ou? (normalmente não são os dois? ) Se o último, ainda é executado no contexto de algum shell, não é? (uma interativa e sem login?) Então, minha pergunta também é sobre semântica - o que significa "shell de login" e por que o OpenSSH foi projetado para não criar um para comandos únicos?
— quer

@RyanLue Os diferentes "sabores" de shells tornam cada tarefa mais fácil / mais segura / otimizada etc. Enquanto fazem um sshrequer um login, os implementadores aparentemente decidiram que, em algumas circunstâncias, por exemplo, pedindo para executar um comando e retornar, faça não precisam / se beneficiam das etapas extras que um shell de logon executa e, portanto, pulam isso. Portanto, de fato, existe um shell que é executado, presumo principalmente configurar o ambiente e, como o shell não será fornecido ao usuário que efetuou login, eles o tratam como se o usuário tivesse iniciado um novo shell para executar esse ambiente. comando
— Eric Renouf

"Então, de fato, existe um shell que é executado, presumo principalmente configurar o ambiente ..." <, mas apenas experimentei isso e parece que ssh <host> <command>não herda o ambiente de nenhum shell de login existente. Por exemplo, $ ssh <host> \$PATHretorna o caminho como seria sem procurar .bash_profile(ou .profile, por assim dizer) ... Em um sentido prático, por que você deseja contornar esse passo?
— precisa

"... os implementadores aparentemente decidiram que, em algumas circunstâncias, por exemplo, solicitando que ele execute um comando e retorne, não precisa / se beneficia das etapas extras que um shell de logon executa, e então pula isso." <também, procurando especificamente esclarecimentos / informações sobre essa opção de design. Eu defino o meu PATHem .profile- não é que exatamente o tipo de coisa que você quer carregar antes de executar um comando arbitrário em um host remoto?
— precisa

1
@RyanLue, o servidor Boks ssh distingue usos distintos do ssh e pode conceder permissões para cada um. Login remoto, execução remota, cópia remota. Talvez isso ajude a entender por que você teria o comportamento que descreve. O login remoto (uso interativo) pode ser pedir demais em um ambiente de alta segurança. O Openssh pode ser restringido pelo uso de rbash / rksh e 'logout' em .bash_profile ou chroot.
— bbaassssiiee

4

O porquê desse comportamento está em um nível mais baixo do que os shells: ssh host(o caso "shell de login") usa um pseudoterminal no host remoto para se comunicar entre o sshdprocesso do servidor e o shell; ssh host commandusa tubos entre sshde command, em vez disso. Os pseudo-terminais são necessários para fazer uso interativo de um interpretador de comandos, como um shell, ou o modo " leitura-avaliação-impressão " de uma linguagem de script; eles implementam vários recursos amigáveis ​​ao ser humano, como poder retroceder com erros de digitação. Mas eles têm mais sobrecarga e (dependendo da configuração) não permitem que dados arbitrários passem sem modificação, portanto o SSH evita usá-los quando a interação não está acontecendo.

Às vezes, a heurística de comando / sem comando do SSH erra; ele pode ser substituído pelos botões -te -T. Por exemplo, para fazer login em uma máquina remota e reconectar imediatamente uma screensessão suspensa , é necessário fazer ssh -t host screen -R; ssh host screen -Rfará com screenque reclamar por não estar conectado a um terminal. Não consigo pensar em uma situação em que você realmente queira usar -T, mas está lá se você encontrar uma.


1

Primeiro você precisa ver os diferentes tipos, você pode ler isto:

/unix/170493/login-non-login-and-interactive-non-interactive-shells

Agora, se você abrir o bashrc, verá no início isso:

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

Isso significa que, dependendo de como você está acessando o sistema, esse arquivo carrega o código dentro ou não.


Ok, mas isso levanta uma questão interessante: .bashrcpode ser escrito para não ser originado se for chamado em um contexto não interativo ( ou seja, se não houver uma "declaração rápida" / $PS1variável). Mas ssh <host> <command> é decididamente não interativo ; isto é, não gera um prompt de comando. Então, por que o OpenSSH foi projetado para criar um prompt interativo sem login (que tenta se originar .bashrc) para este caso de uso aparentemente interativo e não interativo?
— precisa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.