Como forçar o comando ssh a executar no sistema remoto em vez de localmente

3

Eu tenho SSH executando alguns comandos em um script, assim:

#!/bin/bash

REMOTEUSER=$1
REMOTEHOST=$2    
newVh=$3

ssh "$REMOTEUSER"@"$REMOTEHOST" << EOF

cd

if [ ! -d "/data/web/someDirectory" ]
then
  echo -e "There is no vhost setup for someDirectory"
  exit 1
fi


if [ ! -d "git" ]
then
  echo -e "Home git directory not found. Creating it now."
  mkdir git
fi

if [ ! -d "git/$newVh.git" ]
then
  echo -e "Bare git repository not found for $new. Creating it now."
  mkdir git/"$newVh".git
  git init --bare git/"$newVh".git
fi


EOF

O que funciona bem e faz o que eu quero. Eu estou tentando verificar se o compass ruby gem está instalado na máquina remota e se não for, eu quero instalá-lo. Eu adicionei esta linha na parte inferior do script:

.
.
.
if [ 'gem list compass -i' == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi


EOF

Mas 'gem list compass -i' . está sendo avaliado em minha máquina local de antemão (eu tenho bússola instalado). Mesmo executando gem list compass -i no script sem aspas para ver a saída está retornando true , o que é incorreto. Tentei escapar do comando com um número \ s, mas não funcionou.

Eu acho duas perguntas:

Como é possível que outros comandos no script ( mkdir , cd , git init etc ...) funcionem corretamente na máquina remota, mas gem list não funciona?

Como faço para escapar desse comando para executá-lo remotamente?

    
por Brandon 19.10.2017 / 16:37

1 resposta

4

O problema com seu código original é que a expressão de substituição de comando (denotada por back-ticks) é avaliada antes da execução do comando ssh . Em uma situação diferente, você pode considerar citando a palavra-chave here-doc (por exemplo, "EOF") para evitar a expansão de parâmetros em seu aqui-doc, mas neste caso você realmente deseja executar alguma substituição de parâmetro no lado do cliente. Então, uma solução aqui poderia ser escapar da substituição de comando. Tente isso:

if [ \'gem list compass -i\' == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

Os back-ticks evitados impedem que a substituição de comandos seja avaliada.

Eu também mencionarei que a sintaxe de back-tick para substituição de comandos é amplamente considerada como um recurso legado e que a sintaxe do sinal de dólar é geralmente preferida nos dias de hoje. Aqui está como o snippet acima ficaria com a sintaxe do sinal de dólar:

if [ \$(gem list compass -i) == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

Para mais informações sobre as diferenças entre as duas notações, você pode consultar as seguintes postagens do StackExchange:

Você também pode querer olhar para a página de manual do GNU Bash sobre a substituição de comandos .

E também na página de manual do GNU Bash sobre redirecionamento .

Observe, em particular, a seguinte subseção aqui:

3.6.6 Here Documents

This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input (or file descriptor n if n is specified) for a command.

The format of here-documents is:

[n]<<[-]word
    here-document
delimiter

No parameter and variable expansion, command substitution, arithmetic expansion, or filename expansion is performed on word. If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ‘'’.

If the redirection operator is ‘<<-’, then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.

    
por 19.10.2017 / 17:55