Por que o $ PATH de um comando remoto ssh difere daquele de um shell interativo?

17

Eu tenho um usuário que não fez modificações no $ PATH em nenhum arquivo de pontos: é exatamente a configuração padrão do sistema. De um shell de login:

$ ssh example.com
[email protected]:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

[email protected]:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Exatamente conforme especificado em /etc/profile . Isso eu acho bastante inesperado:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Como eu disse, não há modificação de $ PATH em ~/.bashrc nem em /etc/bash.bashrc . Nenhum ~/.ssh/environment . O ssh(1) declara que a variável de ambiente PATH é

Set to the default PATH, as specified when compiling ssh.

mas este tópico de StackOverflow e este artigo lista de discussão sugere que eu deveria seja capaz de influenciar o $ PATH para um dado comando simplesmente modificando o / etc / profile, um dos arquivos de inicialização do shell, etc.

O que está acontecendo aqui?

    
por troutwine 20.01.2012 / 01:43

4 respostas

16

A partir da página de manual ssh(1) : "Se o comando for especificado, ele será executado no host remoto em vez de um shell de login."

Então, resumindo, quando você realmente loga na máquina, o bash é iniciado como um shell de login e carrega os arquivos apropriados, quando você se conecta remotamente e emite um comando no lugar do bash, o que significa que esses arquivos NÃO carga. Você pode contorná-lo usando su -l -c ou similar na parte de comando do ssh.

Em alguns casos, vi -t argumento para o trabalho ssh (alocar tty) também.

Editar 1 :
Eu acho que as informações do PATH que você encontrou, que o caminho padrão (a menos que nós o sobrescrevamos) é o compilado no sshd. Certifiquei-me de que meu / etc / profile, / etc / bash *, dotfiles locais, etc. não possuísse nenhuma informação de PATH, então eu fiz logon e ainda tinha um PATH. Eu procurei por este em sshd e encontrei lá. Então é assim que a manpage diz:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Em seguida, adiciono PATH=$PATH:/my/test ao topo do arquivo .bashrc no controle remoto e verifique novamente:

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

Então eu posso absolutamente influenciá-lo, e o PATH padrão é aquele compilado em sshd. :)

    
por 20.01.2012 / 02:03
3

Consegui que o ssh executasse comandos usando o caminho remoto executando:

ssh dist@d6 "bash --login -c 'env'"

Aqui env pode ser substituído pelo comando que você quiser.

Eu autorizei chaves, então não precisei de uma senha para executar o comando ou ssh.

    
por 26.04.2012 / 17:18
3

Eu criei uma solução diferente para resolver o problema. Minha preferência pessoal é criar novos arquivos de configuração em vez de alterar os existentes. Dessa forma, posso facilitar as mudanças na configuração padrão.

Aqui estão os conteúdos de /etc/profile.d/ssh_login.sh :

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

Usando dropbear no lugar de openssh-server (isso também deve funcionar com o openssh), a variável SSH_CONNECTION será configurada automaticamente quando eu fizer login remotamente. Eu criei uma nova configuração de perfil de shell para detectar logins SSH, exibir algumas informações na tela e, o mais importante, carregar as configurações de ambiente global de /etc/environment para substituir os valores compilados. Por favor, note que isso afeta somente shells interativos de SSH, não a execução de comandos remotos.

Alternativamente , se você usar openssh e sempre quiser carregar o ambiente global, independentemente de ser um shell interativo, você pode colocar um symlink em ~/.ssh/ da seguinte forma:

ln -s /etc/environment ~/.ssh/environment

Você precisa ativar a opção PermitUserEnvironment em /etc/sshd/sshd_config . Somente faça isso para usuários confiáveis, pois isso pode permitir que eles ignorem restrições de acesso em algumas configurações usando mecanismos como LD_PRELOAD. Por favor, veja man sshd_config para mais informações, especificamente como usar Match blocos para opções de restrição para usuários / grupos específicos.

    
por 16.01.2013 / 16:08
0

Se você quiser que o caminho do perfil seja carregado, tente:

#!/bin/bash -i

no topo do script. Dessa forma, o shell está no modo interativo ao executar o script.

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.

link

    
por 16.01.2013 / 17:06

Tags