Misturando variáveis locais e remotas e uso e cotação adequados

2

O padrão recomendado para o bash, até onde eu sei, é sempre citar as variáveis do shell.
Por exemplo. "$VAR" em vez de $VAR .
Mas como posso alcançar a mesma segurança que as citações fornecem para variáveis que devem ser interpretadas remotamente ?
Por exemplo, no seguinte:

ssh server.com<<CODE
TARGET="target dir"
COUNT= \$( ls /foo/bar/\$TARGET | wc -l )  
echo \$COUNT > count.txt    

CODE   

Para que o código funcione, preciso escapar de $COUNT e $TARGET .
Mas como obtenho a mesma segurança que o "$ COUNT" ou "$ TARGET" fornece para este caso específico?

Atualizar
Eu colei apenas a parte que é problemática. Eu também tenho outras linhas que as variáveis são definidas fora do heredoc por isso, se eu usar <<'CODE' , em seguida, o fragmento quebra.
Para um exemplo mais completo:

SOME_STRING="SOME VALUE"  
ssh server.com<<CODE  
echo $SOME_VALUE > test_file.txt  # <--- does not work if I use <<'CODE'
TARGET="target dir"
COUNT= \$( ls /foo/bar/\$TARGET | wc -l )  
echo \$COUNT > count.txt    

CODE   
    
por Jim 20.10.2017 / 14:25

2 respostas

1

Parece que aqui os docs deixam aspas duplas no lugar. Por exemplo, considere o seguinte comando:

cat <<HEREDOC
"this will still be quoted"
HEREDOC

Isso produzirá a seguinte string entre aspas como sua saída:

"this will still be quoted:

Então você deve ser capaz de citar suas variáveis como de costume:

SOME_STRING="SOME VALUE"
ssh server.com<<CODE
echo "$SOME_VALUE" > test_file.txt
TARGET="target dir"
COUNT="\$( ls /foo/bar/\$TARGET | wc -l )"
echo "\$COUNT" > count.txt
CODE

A respeito de cotar variáveis dentro de substituições de comandos, consulte o seguinte post: $ (substituição de comando) no Bash

Note que eu copiei o seu snippet textualmente, mas parece que você provavelmente quis usar a variável SOME_STRING em vez de SOME_VALUE . Esta é uma versão ligeiramente modificada do seu snippet que posso executar localmente com os resultados esperados:

mkdir -p "/foo/bar/target dir"

SOME_STRING="SOME VALUE"
ssh localhost<<CODE
echo "$SOME_STRING" > test_file.txt
TARGET="target dir"
COUNT="\$( ls "/foo/bar/\$TARGET" | wc -l )"
echo "\$COUNT" > count.txt
CODE
    
por 20.10.2017 / 15:06
-1

Parece que temos muitas variações nesta questão nos últimos dias.

Nesse caso, cite o documento aqui:

ssh server.com <<'CODE'
TARGET="target dir"
COUNT= $( ls /foo/bar/$TARGET | wc -l )  
echo $COUNT > count.txt    
then  
fi  
CODE  

O 'CODE' (em oposição a apenas CODE ) garantirá que o documento here seja passado para o utilitário como está escrito, sem expandir variáveis ou executar substituições de comandos.

Observe que você também tem erros de sintaxe no documento here (espaços em torno de = e nenhum if ta correspondem ao then ). Você também deve citar duas vezes as expansões $COUNT e $TARGET como de costume.

ssh server.com <<'CODE'
TARGET="target dir"
COUNT=$( ls "/foo/bar/$TARGET" | wc -l )  
printf '%s\n' "$COUNT" >count.txt    
CODE 

Se você estiver tentando contar o número de arquivos em um diretório remoto, use-o:

ssh server 'find "/path/to/dir" -maxdepth 1 -type f -exec echo . \;' | wc -l

Isso contará corretamente o número de arquivos em /path/to/dir .

Para gravar o resultado em um arquivo remoto:

ssh server 'find "/path/to/dir" -maxdepth 1 -type f -exec echo . \; | wc -l >file'

Se o código que você precisa executar remotamente é muito complexo, talvez seja melhor criar um script no servidor para executá-lo. A variável que você precisa passar para o script pode ser passada em sua linha de comando:

ssh server ./script.sh "$SOME_VARIABLE"

O script:

#!/bin/sh

VAR="$1"

# do stuff
    
por 20.10.2017 / 14:39