web-dev-qa-db-fra.com

Passer des variables dans la commande ssh distante

Je veux pouvoir exécuter une commande à partir de ma machine avec ssh et passer à travers la variable d'environnement $BUILD_NUMBER

Voici ce que j'essaye:

ssh [email protected] '~/tools/myScript.pl $BUILD_NUMBER'

$BUILD_NUMBER est défini sur la machine effectuant l'appel ssh et comme la variable n'existe pas sur l'hôte distant, elle n'est pas récupérée.

Comment passer la valeur de $BUILD_NUMBER?

72
Fergal

Si tu utilises

ssh [email protected] "~/tools/run_pvt.pl $BUILD_NUMBER"

au lieu de

ssh [email protected] '~/tools/run_pvt.pl $BUILD_NUMBER'

votre shell interpolera le $BUILD_NUMBER avant d'envoyer la chaîne de commande à l'hôte distant.

140
sarnold

Les variables entre guillemets simples ne sont pas évaluées. Utilisez des guillemets doubles:

ssh [email protected] "~/tools/run_pvt.pl $BUILD_NUMBER"

Le shell développera les variables entre guillemets, mais pas entre guillemets. Cela va changer dans votre chaîne désirée avant d'être passé à la commande ssh.

25
Stephen

(Cette réponse peut paraître inutilement compliquée, mais elle est facilement extensible et robuste en ce qui concerne les espaces et les caractères spéciaux, à ma connaissance.)

Vous pouvez alimenter des données directement via l'entrée standard de la commande ssh et read à partir de l'emplacement distant.

Dans l'exemple suivant,

  1. un tableau indexé est rempli (pour plus de commodité) avec les noms des variables dont vous voulez récupérer les valeurs du côté distant.
  2. Pour chacune de ces variables, nous donnons à ssh une ligne à zéro terminal donnant le nom et la valeur de la variable.
  3. Dans la commande shh elle-même, nous parcourons ces lignes pour initialiser les variables requises.
# Initialize examples of variables.
# The first one even contains whitespace and a newline.
readonly FOO=$'apjlljs ailsi \n ajlls\t éjij'
readonly BAR=ygnàgyààynygbjrbjrb

# Make a list of what you want to pass through SSH.
# (The “unset” is just in case someone exported
# an associative array with this name.)
unset -v VAR_NAMES
readonly VAR_NAMES=(
    FOO
    BAR
)

for name in "${VAR_NAMES[@]}"
do
    printf '%s %s\0' "$name" "${!name}"
done | ssh [email protected] '
    while read -rd '"''"' name value
    do
        export "$name"="$value"
    done

    # Check
    printf "FOO = [%q]; BAR = [%q]\n" "$FOO" "$BAR"
'

Sortie:

FOO = [$'apjlljs ailsi \n ajlls\t éjij']; BAR = [ygnàgyààynygbjrbjrb]

Si vous n’avez pas besoin de export, vous devriez pouvoir utiliser declare au lieu de export.

Un version très simplifiée (si vous n'avez pas besoin de l'extensibilité, ne devez traiter qu'une seule variable, etc.) ressemblerait à ceci:

$ ssh [email protected] 'read foo' <<< "$foo"
1
Alice M.

Comme indiqué précédemment, il n'est pas nécessaire de définir la variable d'environnement sur l'hôte distant. Au lieu de cela, vous pouvez simplement effectuer la méta-expansion sur l'hôte local et transmettre la valeur à l'hôte distant.

ssh [email protected] '~/tools/run_pvt.pl $BUILD_NUMBER'

Si vous voulez vraiment définir la variable d'environnement sur l'hôte distant et l'utiliser, vous pouvez utiliser le programme env

ssh [email protected] "env BUILD_NUMBER=$BUILD_NUMBER ~/tools/run_pvt.pl \$BUILD_NUMBER"

Dans ce cas, c'est un peu exagéré, et notez

  • env BUILD_NUMBER=$BUILD_NUMBER fait la méta-expansion sur le localHost
  • la variable d'environnement BUILD_NUMBER distante sera utilisée par
    le shell distant
0
Gilles Gouaillardet