AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 744263
Accepted
Anthony
Anthony
Asked: 2023-04-28 00:29:57 +0800 CST2023-04-28 00:29:57 +0800 CST 2023-04-28 00:29:57 +0800 CST

O ssh executa comandos (em vez do próprio shell) em um shell de login?

  • 772

De acordo com man sshd:

 LOGIN PROCESS
      When a user successfully logs in, sshd does the following:

      <...>

            9.   Runs user's shell or command.  All commands are run under the
                 user's login shell as specified in the system password data‐
                 base.

Não está claro, porém, "executar sob o shell de login do usuário" significa literalmente "shell de login, como em bash -l"? Minhas experiências mostram que não, não é:

$ ssh u@h shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Not login shell

Eu não posso ver por que isso é assim? Isso resulta em comandos sendo executados, não obtendo o ambiente usual, pois apenas faz login no shell. Isso é complicado.

shell
  • 2 2 respostas
  • 248 Views

2 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-04-28T00:44:33+08:002023-04-28T00:44:33+08:00

    shell de login pode significar duas coisas diferentes nesse contexto:

    1. o shell que é definido como o shell de login para o usuário no banco de dados da conta.

      Por exemplo:

      $ getent passwd stephane
      stephane:*:1000:1000:Stephane Chazelas:/home/stephane:/bin/zsh
      

      /bin/zshé o meu shell de login, o 7º campo na minha entrada no banco de dados da conta. Alguns outros usuários podem ter /bin/tcsh, /bin/fish, /bin/bash, /sbin/nologin, /bin/false...

    2. uma invocação de um shell usado para inicializar uma sessão de argv[0]login , aquelas que geralmente são feitas por login / -sshd -l... --logincomo .profile, .login, .zlogin, etc.

    Em qualquer caso, o shin sshé para shell e, sshdcomo rshdantes, sempre invoca um shell para interpretar o código enviado pelo cliente, se houver.

    Se você executar:

    ssh user@host foo    bar
    

    Onde fooe baros argumentos são passados ​​para ssh, sshjunta-os com espaços e envia o foo barcódigo shell para o servidor.

    O servidor hostexecutará o shell de loginuser com 3 argumentos:

    1. o nome base do shell de login. No meu casozsh
    2. -c
    3. o código dado pelo cliente: foo barnesse exemplo

    E o shell interpretará isso como código em sua própria sintaxe¹, não será executado como um shell de login, argv[0]não começa com um arquivo -.

    Se nenhum argumento for passado para o cliente, como quando é invocado como:

    ssh user@host
    

    rloginEm seguida, entra-se no modo (como rshaquele usado para executar rlogin quando não é passado um comando), então um pseudo-tty é usado e sshdexecuta o shell de login do usuário com apenas um argumento ( argv[0]):

    1. o nome base do shell de login prefixado com um -, no meu caso -zsh.

    E isso diz ao shell que ele está sendo executado como um shell de login e ele irá ler .zprofile / .profile/ .login.

    Entao, para resumir:

    • ssh host shell-codeé como rsh host shell-codee executa um comando remotamente fazendo com que o shell de login do usuário remoto analise algum código.
    • ssh hosté como rlogin host, e efetua login remotamente iniciando seu shell de login no modo de shell de login em um terminal virtual.

    ¹ para este muito simples, exceto para /bin/falseou /sbin/nologiné claro e talvez para usuários que gostam de ter /usr/bin/python3como shell de login, o código será interpretado da mesma forma por todos os shells, mas para os mais complexos, haverá alguma variação. Veja também Como executar um comando simples arbitrário sobre ssh sem conhecer o shell de login do usuário remoto?

    • 11
  2. Gilles 'SO- stop being evil'
    2023-04-28T01:00:34+08:002023-04-28T01:00:34+08:00

    Não, o SSH apenas invoca um shell de login ao fazer login em um shell, não ao executar um comando. Isso significa que, se você deseja que seus arquivos de inicialização de login sejam executados (por exemplo ~/.profile, ), você precisa fazer isso explicitamente. Esta é uma escolha de design deliberada: nos dias em que a maioria dos logins era em um terminal de texto, muitos usuários executavam comandos em seus .profileque só faziam sentido ao fazer login para uma sessão interativa. (Isso é muito menos comum agora que a maioria das pessoas faz login localmente em uma sessão gráfica.) Você não gostaria de um rápido ssh example.com ls, ou pior, um rsync example.com:somefile ., para iniciar o Emacs e ligar seu modem para buscar seu e-mail!


    O comando no SSH é uma string, obtida pela concatenação dos argumentos da linha de comando com um espaço entre eles. Por exemplo, ssh u@h shopt -q login_shellexecuta o comando shopt -q login_shell. É exatamente equivalente a ssh u@h 'shopt -q login_shell', ou ssh u@h 'shopt -q' login_shell, etc.

    O SSH passa essa string para o shell de login do usuário. O SSH não conhece nenhum outro shell. O servidor pode estar executando em um sistema não-Unix ou em um ambiente restrito onde não há nenhum programa chamado shou bash.

    O servidor SSH executa o executável listado no banco de dados do usuário como o shell de login do usuário, mas não necessariamente como um shell de login. Quando a linha de comando não está vazia, ela passa uma lista de três argumentos:

    • argv[0]é o nome base do programa, seguindo a convenção usual.
    • argv[1]é a corda -c.
    • argv[2]é o comando passado pelo cliente.

    Para uma linha de comando vazia, o servidor SSH chama o shell de login do usuário como um shell de login . Isso significa uma lista de um argumento:

    • argv[0]é um traço ( -) seguido do nome base do programa.

    Por exemplo, aqui está a saída de ssh localhost 'cat /proc/$$/cmdline | tr \\0 \\n'em uma máquina Linux:

    sh
    -c
    cat /proc/$$/cmdline | tr \\0 \\n
    

    Para um shell de login, é mais difícil de observar, porque o próprio shell de login geralmente executa outros programas. A maneira mais fácil de ver o que está acontecendo é desabilitar temporariamente o(s) arquivo(s) de inicialização do shell de login, por exemplo, renomeando temporariamente ~/.profile(ou ~/.bash_profile, ~/.zprofile, etc. dependendo de qual shell você usa). Aqui está um exemplo em uma conta com /bin/sho shell de login:

    $ mv ~/.profile ~/not.profile
    $ ssh localhost
    (/etc/motd content goes here)
    Last login: Mon Apr 24 18:00:30 2023
    $ cat /proc/$$/cmdline; echo
    -sh
    $ exit
    Connection to localhost closed.
    $ mv ~/not.profile ~/.profile
    
    • 9

relate perguntas

  • Como funciona este comando? mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve