/etc/profile.d e “ssh -t”

3

Eu queria executar um script em uma máquina remota. A solução simples é esta:

ssh remote1 some-script

Isso funciona até que o script remoto não deseje se conectar a outra máquina remota ( remote2 ), o que requer autenticação interativa, como esta ( remote2 é acessível somente por remote1 neste caso):

ssh remote1 "ssh remote2 some-script"

A solução para o problema é usar a opção -t para ssh.

ssh -t remote1 "ssh remote2 some-script"

Isso funciona, mas eu recebo probems no caso de eu usar isso (onde some-script pode executar outros comandos ssh):

ssh -t remote1 some-script

Descobri que algumas variáveis de ambiente não estão definidas, que são definidas quando não uso a opção -t . Essas variáveis de ambiente são definidas em scripts de /etc/profile.d . Eu acho que esses scripts não são executados por algum motivo, se estiver usando a opção -t , mas são executados se eu não usá-lo.

Qual é o motivo disso? Existe alguma maneira de contornar isso? Estou usando o SUSE linux (versão 10).

Editar: fiz algumas pesquisas adicionais. Eu coloquei algumas linhas de saída para os seguintes locais:

  • em um arquivo em /etc/profile.d
  • em ~/.bash_profile (o arquivo não existia antes)
  • em ~/.bashrc (o arquivo não existia antes)

Em seguida, verifiquei vários cenários de qual saída obtive e em qual ordem (a variável de ambiente que eu verifiquei é $PATH ):

  • ssh remote1 : profile.d , .bashrc , .bash_profile . $PATH OK.
  • ssh -t remote1 : profile.d , .bashrc , .bash_profile . $PATH OK.
  • ssh remote1 echo '$PATH' : apenas .bashrc . $PATH OK.
  • ssh -t remote1 echo '$PATH' : sem saída de script. $PATH NOK.

Agora eu realmente não entendo o que está acontecendo. Se eu executar um shell interativo, tudo parece estar funcionando bem (embora ache estranho que ~/.bashrc seja incluído antes de ~/.bash_profile ). Se eu iniciar um shell não interativo sem -t , os scripts de perfil não parecem ser executados, mas as variáveis de ambiente estão definidas. Se eu iniciar um shell não interativo com -t , os detalhamentos de perfil não serão executados e as variáveis de ambiente não serão definidas. Alguém tem uma explicação sobre isso?

    
por petersohn 24.10.2012 / 12:49

3 respostas

0

Não encontrei o motivo do problema. Talvez seja específico para a plataforma (SLES 10 ou a variação que eu uso). Eu encontrei uma solução alternativa:

ssh -t remote1 "/bin/bash --login -c some-script"

Isso força um shell de login que executa scripts de perfil.

    
por 27.10.2012 / 09:07
0

Todas as perguntas são respondidas na seção "INVOCATION" da página man bash:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

When a login shell exits, bash reads and executes commands from the file ~/.bash_logout, if it exists.

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.

Como você pode ver, os shells interativos só acessam .bashrc , e geralmente .bash_profile é originado a partir daí, o que explica a ordem que você está vendo.

Muitas vezes, esses arquivos também têm a condição de apenas analisar certas seções apenas para shells interativos ( [[ $- == *i* ]] ), o que explicaria por que algumas partes podem parecer estar faltando para shells não interativas.

    
por 24.10.2012 / 13:47
0

A diferença entre

ssh remote1 echo '$PATH'

e

ssh -t remote1 echo '$PATH'

também é explicado no bash manpage:

Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by the remote shell daemon, usually rshd, or the secure shell daemon sshd. If bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc [I assume that should read /etc/bash.bashrc] and ~/.bashrc, if these files exist and are readable.

No primeiro exemplo, o stdin de bash está conectado a uma conexão de rede, portanto, ele executa ~/.bashrc . No segundo, seu stdin vem de um pseudo-terminal, então não faz.

    
por 04.12.2017 / 14:57

Tags