Por que um comando remoto SSH obtém menos variables ​​de ambiente do que quando executado manualmente?

Eu tenho um comando que corre bem se eu ssh para uma máquina e executá-lo, mas falha quando tento executá-lo usando um comando ssh remoto como:

ssh user@IP  

Comparando a saída de “env” usando ambos os methods resutls em diferentes ambientes. Quando eu logar manualmente na máquina e executar o env, obtenho muito mais variables ​​de ambiente do que quando eu executo:

 ssh user@IP "env" 

Alguma ideia do porquê?

Existem diferentes tipos de conchas. O shell de execução do comando SSH é um shell não interativo, enquanto o shell normal é um shell de login ou um shell interativo. Descrição segue, do homem bash:

        Um shell de login é aquele cujo primeiro caractere de argumento
        zero é um -, ou um iniciado com a opção --login.

        Um shell interativo é iniciado sem opção
        argumentos e sem a opção -c, cuja input padrão
        e erro são ambos conectados aos terminais (como determinado
        por isatty (3)), ou um iniciado com a opção -i.  PS1 é
        set e $ - inclui i se bash é interativo, permitindo um
        script de shell ou um arquivo de boot para testar esse estado.

        Os parágrafos a seguir descrevem como o bash executa sua
        arquivos de boot.  Se algum dos arquivos existir, mas não puder ser
        leia, bash relata um erro.  Tils são expandidos em arquivo
        nomes como descrito abaixo em Til Expansion no
        Seção EXPANSÃO.

        Quando o bash é invocado como um shell de login interativo ou como
        um shell não interativo com a opção --login, primeiro
        lê e executa comandos do arquivo / etc / profile, se
        esse arquivo existe.  Depois de ler esse arquivo, ele procura
        ~ / .bash_profile, ~ / .bash_login e ~ / .profile, nesse
        ordem, e lê e executa comandos do primeiro
        que existe e é legível.  A opção --noprofile pode
        ser usado quando o shell é iniciado para inibir este comportamento
        eu ou.

        Quando um shell de login sai, o bash lê e executa comandos
        do arquivo ~ / .bash_logout, se existir.

        Quando um shell interativo que não é um shell de login é
        iniciado, o bash lê e executa comandos de ~ / .bashrc,
        se esse arquivo existir.  Isso pode ser inibido usando o
        Opção --norc.  A opção do arquivo --rcfile forçará o bash
        ler e executar comandos do arquivo em vez de
        ~ / .bashrc.

        Quando o bash é iniciado de forma não interativa, para executar um shell
        script, por exemplo, procura a variável BASH_ENV em
        o meio ambiente, expande seu valor se aparecer lá,
        e usa o valor expandido como o nome de um arquivo para ler
        e execute.  O Bash se comporta como se o seguinte comando
        foram executados:
               if [-n "$ BASH_ENV"];  então .  "$ BASH_ENV";  fi
        mas o valor da variável PATH não é usado para pesquisar
        para o nome do arquivo.

Como cerca de terceirização do perfil antes de executar o comando?

ssh user@host "source /etc/profile; /path/script.sh"

Você pode achar melhor mudar isso para ~/.bash_profile , ~/.bashrc , ou o que for.

(Como aqui (linuxquestions.org) )

O ambiente do shell não é carregado ao executar o comando ssh remoto. Você pode editar o arquivo de ambiente ssh:

 vi ~/.ssh/environment 

Seu formato é:

 VAR1=VALUE1 VAR2=VALUE2 

Além disso, verifique a configuração do sshd para a opção PermitUserEnvironment = yes.

Eu tive um problema semelhante, mas no final eu descobri que ~ / .bashrc era tudo que eu precisava.

No entanto, no Ubuntu, tive que comentar a linha que para o processamento do ~ / .bashrc:

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

Eu encontrei uma resolução fácil para este problema foi adicionar origem / etc / profile para o topo do arquivo script.sh que eu estava tentando executar no sistema de destino. Nos sistemas aqui, isso fazia com que as variables ​​ambientais que eram necessárias pelo script.sh fossem configuradas como se estivessem sendo executadas a partir de um shell de login.

Em uma das respostas anteriores, foi sugerido que ~ / .bashr_profile etc … fosse usado. Eu não gastei muito tempo nisso, mas, o problema com isso é se você ssh para um usuário diferente no sistema de destino que o shell no sistema de origem a partir do qual você logou pareceu-me que isso faz com que o usuário do sistema de origem nome a ser usado para o ~.

Basta exportar as variables ​​de ambiente que você deseja acima da verificação de um shell não interativo em ~ / .bashrc.