A passagem de variáveis (variáveis de ambiente) sobre ssh
é possível, mas geralmente restrita.
Você precisa dizer ao cliente para enviá-los. Por exemplo, com o OpenSSH, isso é com:
ssh -o SendEnv=parameter host cmd...
Mas você também precisa do servidor para aceitá-lo ( AcceptEnv
configuration directive with OpenSSH). Aceitar qualquer variável é um grande risco de segurança, portanto, geralmente não é feito por padrão, embora algumas implantações ssh permitam algumas variáveis em algum namespace (como LC_*
em algumas implantações do OpenSSH).
Você também precisa exportar a variável antes de chamar ssh
, como:
LC_parameter="$parameter" ssh -o SendEnv=LC_parameter host csh << 'END'
echo $LC_parameter:q
END
Acima, estamos passando o conteúdo da variável $parameter
bash
shell como a variável de ambiente LC_parameter
para ssh
. ssh
envia para sshd
, que, se o aceitar, passa como uma variável de ambiente para o shell de login do usuário, que então passa para o comando csh
(que pode expandi-lo).
Mas, como mencionado anteriormente, isso não funcionará, a menos que o administrador da máquina host
tenha adicionado AcceptEnv LC_parameter
ou AcceptEnv LC_*
(que às vezes é feito por padrão) à configuração sshd
.
A mensagem de erro Undefined variable
no seu exemplo sugere que o shell de login do usuário remoto é csh
ou tcsh
. É melhor invocar explicitamente o shell para evitar surpresas ( ssh host csh
também significa que um tty não é solicitado, portanto você não precisa de -T
). Observe a sintaxe $LC_parameter:q
, que é a maneira de csh
de passar o conteúdo de uma variável textualmente, não de "$LC_parameter"
, o que não funciona se a variável contiver caracteres de nova linha.
Se usar LC_*
variables não for uma opção, então, alternativamente, você pode ter o shell client ( bash
no seu caso) expandir a variável. Um jeito ingênuo seria com
ssh host csh << END
echo "$variable"
END
Mas isso seria perigoso, pois o conteúdo da variável seria interpretado pelo shell remoto. Se $variable
contiver 'reboot'
ou "; reboot; : "
, por exemplo, isso teria consequências ruins.
Então, você precisa primeiro verificar se a variável está corretamente citada na sintaxe do shell remoto. Aqui, eu evitaria csh
onde é difícil fazer de forma confiável e usar sh
/ bash
/ ksh
.
Use uma função auxiliar para fazer a cotação:
shquote() {
awk -v q=\' -v b='\' '
BEGIN{
for (i=1; i<ARGC; i++) {
gsub(q, q b q q, ARGV[i])
printf "%s ", q ARGV[i] q
}
print ""
exit
}' "$@"
}
E chame ssh
como:
ssh host sh << END
parameter=$(shquote "$parameter")
echo "\$parameter"
END
Veja como escapamos o terceiro $
, então a expansão de $parameter
é feita pelo shell remoto, não pelo local.