Übergeben von Variablen im Remote-Befehl ssh

98

Ich möchte in der Lage sein, einen Befehl von meinem Computer mit ssh auszuführen und die Umgebungsvariable zu übergeben $BUILD_NUMBER

Folgendes versuche ich:

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

$BUILD_NUMBER wird auf dem Computer festgelegt, der den SSH-Aufruf ausführt, und da die Variable auf dem Remote-Host nicht vorhanden ist, wird sie nicht erfasst.

Wie übergebe ich den Wert von $BUILD_NUMBER?

Fergal
quelle
1
unabhängig von Hudson, entfernte das Tag. (Hudson erstellt nur die Variable)
Peter Schuetze

Antworten:

187

Wenn du benutzt

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

anstatt

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

Ihre Shell interpoliert die $BUILD_NUMBERvor dem Senden der Befehlszeichenfolge an den Remote-Host.

Sarnold
quelle
8
Wenn jemand einfache Anführungszeichen verwenden MUSS, damit der in den Anführungszeichen enthaltene Befehl nicht lokal ausgewertet wird, sollte er "'$ VARIABLE'" verwenden. Beispiel: ssh [email protected] '~ / tools / run_pvt.pl "' $ BUILD_NUMBER '"'
dr.doom
3
Ich wusste nicht, dass Bash mit einfachen und doppelten Anführungszeichen unterschiedlich reagiert. Vielen Dank!
Silgon
1
Linux-Core-Entwickler müssen in der Hölle brennen
Goldstar
@goldstar, beachten Sie, dass der Unterschied zwischen einfachem und doppeltem Anführungszeichen in der Shell Jahrzehnte vor Linux liegt.
Sarnold
3
PSA: Wenn Ihre Zeichenfolge Benutzereingaben enthält, ist dies eine sehr schlechte Idee und kann Sie für Code-Injection-Angriffe öffnen.
Brian McCutchon
27

Variablen in einfachen Anführungszeichen werden nicht ausgewertet. Verwenden Sie doppelte Anführungszeichen:

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

Die Shell erweitert Variablen in doppelten Anführungszeichen, jedoch nicht in einfachen Anführungszeichen. Dies ändert sich in die gewünschte Zeichenfolge, bevor sie an den sshBefehl übergeben wird.

Stephen
quelle
2

(Diese Antwort mag unnötig kompliziert erscheinen, ist aber meines Wissens leicht erweiterbar und robust in Bezug auf Leerzeichen und Sonderzeichen.)

Sie können Daten direkt über die Standardeingabe des sshBefehls und readdie vom Remote-Standort aus eingeben.

Im folgenden Beispiel

  1. Ein indiziertes Array wird (der Einfachheit halber) mit den Namen der Variablen gefüllt, deren Werte Sie auf der Remote-Seite abrufen möchten.
  2. Für jede dieser Variablen geben wir ssheine nullterminierte Zeile an, die den Namen und den Wert der Variablen angibt.
  3. Im shhBefehl selbst durchlaufen wir diese Zeilen, um die erforderlichen Variablen zu initialisieren.
# 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"
'

Ausgabe:

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

Wenn Sie diese nicht benötigen export, sollten Sie sie declareanstelle von verwenden können export.

Eine wirklich vereinfachte Version (wenn Sie die Erweiterbarkeit nicht benötigen, eine einzelne Variable verarbeiten müssen usw.) würde folgendermaßen aussehen:

$ ssh user@somehost.com 'read foo' <<< "$foo"
Alice M.
quelle
2

Die Liste der akzeptierten Umgebungsvariablen auf SSHD enthält standardmäßig LC_*. So:

LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
1.2.3
Alex Stragies
quelle
0

Wie bereits beantwortet, müssen Sie die Umgebungsvariable nicht auf dem Remote-Host festlegen. Stattdessen können Sie einfach die Metaerweiterung auf dem lokalen Host durchführen und den Wert an den Remote-Host übergeben.

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

Wenn Sie die Umgebungsvariable wirklich auf dem Remote-Host festlegen und verwenden möchten, können Sie das envProgramm verwenden

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

In diesem Fall ist dies ein bisschen übertrieben, und beachten Sie

  • env BUILD_NUMBER=$BUILD_NUMBER führt die Metaerweiterung auf dem lokalen Host durch
  • Die Remote- BUILD_NUMBERUmgebungsvariable wird von
    der Remote-Shell verwendet
Gilles Gouaillardet
quelle
0

Es ist auch möglich, Umgebungsvariablen explizit über ssh zu übergeben. Es erfordert einige serverseitige Einstellungen, daher ist dies keine universelle Antwort.

In meinem Fall wollte ich einen Sicherungsrepository-Verschlüsselungsschlüssel an einen Befehl auf dem Sicherungsspeicherserver übergeben, ohne dass dieser Schlüssel dort gespeichert ist. Beachten Sie jedoch, dass alle Umgebungsvariablen in sichtbar sind ps ! Die Lösung, den Schlüssel an stdin weiterzugeben, würde ebenfalls funktionieren, aber ich fand es zu umständlich. In jedem Fall erfahren Sie hier, wie Sie eine Umgebungsvariable über ssh übergeben:

Bearbeiten Sie die sshd_configDatei normalerweise auf dem Server /etc/ssh/sshd_configund fügen Sie eine AcceptEnvDirektive hinzu, die den Variablen entspricht, die Sie übergeben möchten. Siehe man sshd_config. In meinem Fall möchte ich Variablen an borg backup übergeben, also habe ich gewählt:

AcceptEnv BORG_*

Verwenden Sie jetzt auf dem Client die -o SendEnvOption, um Umgebungsvariablen zu senden. Die folgende Befehlszeile legt die Umgebungsvariable fest BORG_SECRETund markiert sie dann zum Senden an den Clientcomputer (aufgerufen backup). Dort wird es dann ausgeführt printenvund die Ausgabe nach BORG-Variablen gefiltert:

$ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
BORG_SECRET=magic-happens
TvE
quelle
Sie können Ihre Variablen mit den Standardeinstellungen des Servers "schmuggeln", siehe meine Antwort . Das Wesentliche ist, dass die Standard-OpenSSHd-Konfiguration die LC_*zulässigen zu sendenden Variablen enthält. Verwenden Sie also einfach $LC_TvE_foooder $LC_BORG_SECRETstellen Sie sicher, dass Sie nicht mit einer integrierten Variablen "kollidieren".
Alex Stragies
-2

Escape die Variable, um auf Variablen außerhalb der ssh-Sitzung zuzugreifen: ssh [email protected] "~ / tools / myScript.pl \ $ BUILD_NUMBER"

Sarah Gruneisen
quelle
2
Dies erreicht nicht das, was die Frage verlangt.
Patrick Trentin
2
aus der Sicht der Shell '$FOO'ist äquivalent zu "\$FOO". Die Frage war "Wie übergebe ich eine Shell-Variable mit SSH?". Wie bereits von @PatrickTrentin angegeben, ist dies keine korrekte Antwort, da dann die BUILD_NUMBERUmgebungsvariable nicht remote festgelegt wird.
Gilles Gouaillardet