pass variável no ssh

6

Estou tentando passar uma variável para ssh remote, mas não funciona. Meu código é:

#!/bin/bash
set -x
conexion="[email protected]"
parameter="$1"
ssh -T $conexion <<'ENDSSH' 
clear
echo "$parameter"
ENDSSH

Eu executo:

./script.sh try

Isso me diz:

parameter: Undefined variable.

alguma ajuda por favor?

    
por user650034 29.07.2016 / 10:40

3 respostas

6

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.

    
por 29.07.2016 / 11:19
3

Entre outros truques (como passar LC_* variáveis de ambiente), você pode fazer o seguinte:

PARAMETER="123"
ssh user@host PARAMETER="$PARAMETER" bash -s <<- __EOF
    echo \$PARAMETER
__EOF

A vantagem da abordagem é a ausência do requisito de export PARAMETER , adicionando seu nome a AcceptEnv (no caso de nomes que não começam em LC_ ) em config /etc/ssh/sshd_config no host remoto, adicionando a SendEnv no host local (para -o ou para /etc/ssh/ssh_config ).

    
por 12.01.2018 / 11:22
2

A remoção de citações de ENDSSH na quarta linha deve ajudar.

Cortesia: @Archemar em comentários à questão.

AVISO Como foi afirmado por @ StéphaneChazelas no comentário a esta resposta, este sollution faria com que a variável $parameter no documento a seguir fosse expandida pelo shell local, o que significa que o conteúdo da variável seria interpretada como código de shell pelo shell remoto, o que significa que ele introduz uma vulnerabilidade de injeção de comando. Então, geralmente, é desencorajado fazê-lo.

    
por 29.07.2016 / 11:05