Passaggio di variabili nel comando ssh remoto


99

Voglio essere in grado di eseguire un comando dalla mia macchina usando ssh e passare attraverso la variabile d'ambiente $BUILD_NUMBER

Ecco cosa sto provando:

ssh pvt@192.168.1.133 '~/tools/myScript.pl $BUILD_NUMBER'

$BUILD_NUMBER è impostato sulla macchina che effettua la chiamata ssh e poiché la variabile non esiste sull'host remoto, non viene rilevata.

Come si trasferisce il valore di $BUILD_NUMBER?


1
non correlato a Hudson, ha rimosso il tag. (Hudson crea solo la variabile)
Peter Schuetze

Risposte:


188

Se usi

ssh pvt@192.168.1.133 "~/tools/run_pvt.pl $BUILD_NUMBER"

invece di

ssh pvt@192.168.1.133 '~/tools/run_pvt.pl $BUILD_NUMBER'

la tua shell interpolerà il $BUILD_NUMBERprima di inviare la stringa di comando all'host remoto.


8
Se qualcuno DEVE usare virgolette singole in modo che il comando incluso tra virgolette non venga valutato localmente, allora dovrebbe usare "'$ VARIABILE'". Esempio: ssh pvt@192.168.1.133 '~ / tools / run_pvt.pl "' $ BUILD_NUMBER '"'
dr.doom

3
non sapevo che bash reagisce in modo diverso con virgolette singole e doppie. Grazie!
Silgon

1
gli sviluppatori di linux core devono bruciare all'inferno
goldstar

@goldstar, nota che la differenza tra virgolette singole e virgolette doppie nella shell precede Linux di decenni.
sarnold

3
PSA: se la tua stringa contiene l'input dell'utente, questa è una pessima idea e potrebbe aprirti ad attacchi di iniezione di codice.
Brian McCutchon

27

Le variabili tra virgolette singole non vengono valutate. Usa virgolette doppie:

ssh pvt@192.168.1.133 "~/tools/run_pvt.pl $BUILD_NUMBER"

La shell espanderà le variabili tra virgolette doppie, ma non tra virgolette singole. Questo cambierà nella stringa desiderata prima di essere passato al sshcomando.


2

(Questa risposta potrebbe sembrare inutilmente complicata, ma è facilmente estensibile e robusta per quanto riguarda spazi bianchi e caratteri speciali, per quanto ne so.)

È possibile inserire i dati direttamente attraverso lo standard input del sshcomando e readquello dalla posizione remota.

Nell'esempio seguente,

  1. un array indicizzato viene riempito (per comodità) con i nomi delle variabili di cui si desidera recuperare i valori sul lato remoto.
  2. Per ciascuna di queste variabili, diamo a ssh una riga con terminazione nulla che fornisce il nome e il valore della variabile.
  3. Nel shhcomando stesso, eseguiamo un ciclo tra queste righe per inizializzare le variabili richieste.
# 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 user@somehost.com '
    while read -rd '"''"' name value
    do
        export "$name"="$value"
    done

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

Produzione:

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

Se non hai bisogno di exportquelli, dovresti essere in grado di usare al declareposto di export.

Una versione molto semplificata (se non hai bisogno dell'estensibilità, hai una singola variabile da elaborare, ecc.) Sarebbe simile a:

$ ssh user@somehost.com 'read foo' <<< "$foo"

2

L'elenco delle variabili di ambiente accettate su SSHD per impostazione predefinita include LC_*. Quindi:

LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
1.2.3

0

Come risposto in precedenza, non è necessario impostare la variabile di ambiente sull'host remoto. Invece, puoi semplicemente fare la meta-espansione sull'host locale e passare il valore all'host remoto.

ssh pvt@192.168.1.133 '~/tools/run_pvt.pl $BUILD_NUMBER'

Se vuoi veramente impostare la variabile d'ambiente sull'host remoto e usarla, puoi usare il envprogramma

ssh pvt@192.168.1.133 "env BUILD_NUMBER=$BUILD_NUMBER ~/tools/run_pvt.pl \$BUILD_NUMBER"

In questo caso questo è un po 'eccessivo e nota

  • env BUILD_NUMBER=$BUILD_NUMBER esegue la meta espansione sull'host locale
  • la BUILD_NUMBERvariabile di ambiente remota verrà utilizzata dalla
    shell remota

0

È anche possibile passare le variabili d'ambiente esplicitamente tramite ssh. Richiede una configurazione lato server, quindi questa non è una risposta universale.

Nel mio caso, volevo passare una chiave di crittografia del repository di backup a un comando sul server di archiviazione di backup senza che quella chiave fosse memorizzata lì, ma si noti che qualsiasi variabile di ambiente è visibile in ps ! La soluzione di passare la chiave su stdin funzionerebbe anche, ma l'ho trovata troppo ingombrante. In ogni caso, ecco come passare una variabile d'ambiente tramite ssh:

Sul server, modifica il sshd_configfile, in genere /etc/ssh/sshd_confige aggiungi una AcceptEnvdirettiva corrispondente alle variabili che desideri passare. Vedi man sshd_config. Nel mio caso, voglio passare le variabili al backup di borg, quindi ho scelto:

AcceptEnv BORG_*

Ora, sul client usa l' -o SendEnvopzione per inviare variabili d'ambiente. La seguente riga di comando imposta la variabile di ambiente BORG_SECRETe quindi la contrassegna per essere inviata alla macchina client (chiamata backup). Quindi viene eseguito printenvlì e filtra l'output per le variabili BORG:

$ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
BORG_SECRET=magic-happens

Puoi "contrabbandare" le tue variabili utilizzando le impostazioni lato server predefinite, vedi la mia risposta . Il succo è che la configurazione predefinita di OpenSSHd include LC_*come variabili consentite da inviare, quindi usa $LC_TvE_fooo $LC_BORG_SECRETassicurati di non "entrare in collisione" con una variabile incorporata.
Alex Stragies

-2

Esci dalla variabile per accedere alle variabili al di fuori della sessione ssh: ssh pvt@192.168.1.133 "~ / tools / myScript.pl \ $ BUILD_NUMBER"


2
Ciò non ottiene ciò che la domanda chiede.
Patrick Trentin

2
dal punto di vista della shell, '$FOO'è equivalente a "\$FOO". la domanda era "come passare una variabile di shell con SSH?". Come già affermato da @PatrickTrentin questa non è una risposta corretta perché quindi BUILD_NUMBERla variabile d'ambiente non è impostata da remoto.
Gilles Gouaillardet
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.