Quando capturo a saída de uma chamada SSH remota usando cat, seja no bash ou no Python, as coisas funcionam conforme o esperado.
Por exemplo, isso funciona muito bem:
import subprocess
rc = subprocess.getoutput(“ssh user@host; cat /proc/meminfo”)
print(rc)
>> MemTotal: 2048212 kB
MemFree: 202168 kB
MemAvailable: 1578308 kB
Buffers: 240876 kB
Cached: 1073456 kB
SwapCached: 0 kB
Active: 1049444 kB
…etc
No entanto, isso não rende nada:
import subprocess
rc = subprocess.getoutput(“ssh user@host; echo $SHELL”)
>>
Mesmo que o SSHing na máquina como o mesmo usuário e digitando “echo $SHELL” funcione e saia para stdout.
O que estou perdendo aqui?
Nas minhas anotações tenho o seguinte comentário:
Se você quiser disponibilizar qualquer variável de ambiente local para uso no script de shell, inicie o script usando o comando exec.
A execução do script diretamente do prompt de comando gera um novo subshell para o script, tornando quaisquer variáveis de ambiente locais no shell não disponíveis para o script.
Preciso usar 'exec' para que esses env vars sejam disponibilizados a partir de uma execução de comando remoto?
Observe que esta não é apenas uma pergunta do Python ou apenas uma pergunta do RHEL8; é reproduzível em outras variantes do Linux, incluindo o Ununtu.
Obrigado.
Em ambos os casos, o ssh connecton termina e o segundo comando é executado na máquina local . Por exemplo, sua
/proc/meminfo
saída é a da máquina local e não de um controle remoto de forma alguma.Se você quiser executá-lo remotamente, use:
ssh user@host cat /proc/meminfo
— observe a falta de ponto e vírgula, o que torna os argumentos "cat" e "/proc/meminfo" do cliente ssh, a partir do qual ele constrói a linha de comando que é executada remotamente.O segundo caso é ainda mais complicado. Não apenas o ponto e vírgula faz com que seja executado localmente, mas a ordem de substituição também adiciona seus cinco centavos. Na variante ingênua, ele substituirá uma variável localmente e, em seguida, enviará um comando substituído ao controle remoto para executar. Para que ele funcione completamente como desejado, você precisa suprimir a substituição local, para a qual use aspas simples:
ssh user@host echo '$SHELL'
(basta comparar
ssh user@host echo `hostname -f`
essh user@host echo '`hostname -f`'
ver o que quero dizer).Parece que você está pronto para aprender Ansible , porque significava resolver a necessidade de fazer algo sobre SSH remotamente de maneira automatizada.