2017-03-29 1 views
3

J'ai un heredoc qui doit appeler les variables existantes du script principal, et définir ses propres variables à utiliser plus tard. Quelque chose comme ceci:Comment définir ET développer des variables dans une section heredoc

count=0 

ssh $other_host <<ENDSSH 
    if [[ "${count}" == "0" ]]; then 
    output="string1" 
    else 
    output="string2" 
    fi 
    echo output 
ENDSSH 

Cela ne fonctionne pas parce que «sortie» ne se règle sur rien.

J'ai essayé d'utiliser la solution de cette question:

count=0 

ssh $other_host << \ENDSSH 
    if [[ "${count}" == "0" ]]; then 
    output="string1" 
    else 
    output="string2" 
    fi 
    echo output 
ENDSSH 

Il ne fonctionne pas non plus. $ output a la valeur "string2" car $ count n'a pas été développé.

Comment puis-je utiliser un heredoc qui développe des variables du script parent, et définit ses propres variables?

+0

Il se comporte comme prévu. Le code dans heredoc s'exécute sur un hôte distant et ne voit pas l'initialisation 'count = 0'. – codeforester

+0

Existe-t-il un moyen de passer la variable (et quelques autres) dans l'exécution d'heredoc? – user2824889

+3

Il n'y a pas "d'exécution heredoc". L'hérédoc définit une chaîne. La chaîne est passée à ssh, où elle est évaluée par le shell. –

Répondre

3

Vous pouvez utiliser:

count=0 

ssh -t -t "$other_host" << ENDSSH 
    if [[ "${count}" == "0" ]]; then 
    output="string1" 
    else 
    output="string2" 
    fi 
    echo "\$output" 
    exit 
ENDSSH 

Nous utilisons \$output de sorte qu'il est étendu sur un hôte distant pas localement.

+0

Notez également que la valeur de '$ count' est passée du shell actuel au shell distant – anubhava

+0

@ user2824889: Cela a-t-il fonctionné? – anubhava

0

Vous pouvez échapper à des variables comme @anubhava dit, ou, si vous obtenez des variables trop pour l'Évasion, vous pouvez le faire en deux étapes:

# prepare the part which should not be expanded 
# note the quoted 'EOF' 
read -r -d '' commands <<'EOF' 
if [[ "$count" == "0" ]]; then 
    echo "$count - $HOME" 
else 
    echo "$count - $PATH" 
fi 
EOF 

localcount=1 
#use the unquoted ENDSSH 
ssh [email protected] <<ENDSSH 
count=$localcount # count=1 
#here will be inserted the above prepared commands 
$commands 
ENDSSH 

imprimera quelque chose comme:

1 - /usr/bin:/bin:/usr/sbin:/sbin 
1

Il est better not to use stdin (comme en utilisant ici-docs) pour passer des commandes à ssh.

Si vous utilisez un argument de ligne de commande pour passer à la place de vos commandes shell, vous pouvez mieux séparer ce qui est élargi localement et ce qui sera exécuté à distance:

# Use a *literal* here-doc to read the script into a *variable*. 
# Note how the script references parameter $1 instead of 
# local variable $count. 
read -d '' -r script <<'EOF' 
    [[ $1 == '0' ]] && output='zero' || output='nonzero' 
    echo "$output" 
EOF 

# The variable whose value to pass as a parameter. 
# With value 0, the script will echo 'zero', otherwise 'nonzero'. 
count=0 

# Use `set -- '$<local-var>'...;` to pass the local variables as 
# positional parameters, followed by the script code. 
ssh localhost "set -- '$count'; $script"