Por que um comando remoto SSH obtém menos variáveis de ambiente quando executado manualmente?[fechado]
-
03-07-2019 - |
Pergunta
Eu tenho um comando que funciona bem se eu fizer ssh em uma máquina e executá-lo, mas falha quando tento executá-lo usando um comando ssh remoto como:
ssh user@IP <command>
Comparar a saída de "env" usando os dois métodos resulta em ambientes diferentes.Quando faço login manualmente na máquina e executo env, recebo muito mais variáveis de ambiente do que quando executo:
ssh user@IP "env"
Alguma ideia do porquê?
Solução
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.A descrição segue, de man bash:
A login shell is one whose first character of argument zero is a -, or one started with the --login option. An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state. The following paragraphs describe how bash executes its startup files. If any of the files exist but cannot be read, bash reports an error. Tildes are expanded in file names as described below under Tilde Expansion in the EXPANSION section. 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 behav ior. 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. When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi but the value of the PATH variable is not used to search for the file name.
Outras dicas
Que tal obter o 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
, como queiras.
(Como aqui (linuxquestions.org))
O ambiente Shell não carrega 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 sshd para a opção PermitUserEnvironment=yes.
Tive um problema semelhante, mas no final descobri que ~/.bashrc era tudo que eu precisava.
Porém, no Ubuntu, tive que comentar a linha que interrompe o processamento ~/.bashrc :
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
Achei que uma solução fácil para esse problema era adicionar fonte /etc/profile na parte superior do arquivo script.sh que eu estava tentando executar no sistema de destino.Nos sistemas aqui, isso fez com que as variáveis ambientais necessárias ao 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...ser usado.Não gastei muito tempo nisso, mas o problema é que se você fizer ssh para um usuário diferente no sistema de destino do shell no sistema de origem a partir do qual você efetua login, pareceu-me que isso faz com que o usuário do sistema de origem nome a ser usado para ~.
Basta exportar as variáveis de ambiente desejadas acima da verificação de um shell não interativo em ~/.bashrc.