6 Stimmen

Übergabe von Variablen an ein entferntes Skript über SSH

Ich führe Skripte auf einem Remote-Server von einem lokalen Server aus über SSH aus. Das Skript wird zunächst über SCP kopiert und dann aufgerufen, wobei einige Argumente wie folgt übergeben werden:

scp /path/to/script server.example.org:/another/path/

ssh server.example.org \
MYVAR1=1 \
MYVAR2=2 \
/another/path/script

Dies funktioniert gut und auf dem entfernten Server werden die Variablen MYVAR1 y MYVAR2 sind mit ihrem entsprechenden Wert verfügbar.

Das Problem ist, dass diese Skripte ständig weiterentwickelt werden, so dass der SSH-Befehl jedes Mal geändert werden muss, wenn eine Variable umbenannt, hinzugefügt oder entfernt wird.

Ich suche nach einer Möglichkeit, alle lokalen Umgebungsvariablen an das entfernte Skript zu übergeben (da MYVAR1 y MYVAR2 sind eigentlich lokale Umgebungsvariablen), was das Problem der SSH-Befehlswartung lösen würde.

Seit MYVAR1=1 \ y MYVAR1=1 \ sind Linien, die dem env Befehlsausgabe habe ich versucht, sie wie folgt durch den eigentlichen Befehl zu ersetzen:

ssh server.example.org \
`env`
/another/path/script

Dies scheint bei "einfachen" Fällen zu funktionieren. env Ausgabezeilen (z.B. SHELL=/bin/bash o LOGNAME=sysadmin ), aber ich erhalte Fehler für mehr "c LS_COLORS=rs=0:di=01;34:ln=01;[...] was zu Fehlern wie den folgenden führt -bash: 34:ln=01: command not found ). Ich kann diese Fehler loswerden, indem ich die Variablen, die diesen komplexen Ausgabezeilen entsprechen, vor dem Ausführen des SSH-Befehls entferne (z. B. unset LS_COLORS entonces ssh [...] ), aber ich halte diese Lösung nicht für sehr zuverlässig.

F: Weiß jemand, wie man alle lokalen Umgebungsvariablen über SSH an ein entferntes Skript weitergibt?

PS: Die lokalen Umgebungsvariablen sind keine Umgebungsvariablen, die auf dem entfernten Rechner verfügbar sind. daher kann ich diese Lösung nicht verwenden .

Update mit Lösung

Ich benutzte schließlich sed zum Formatieren der env Befehlsausgabe von VAR=VALUE a VAR="VALUE" (und die Verkettung aller Zeilen zu 1), was verhindert, dass die Bash einige der Ausgaben als Befehle interpretiert und mein Problem behebt.

ssh server.example.org \
`env | sed 's/\([^=]*\)=\(.*\)/\1="\2"/' | tr '\n' ' '` \
"/another/path/script"

7voto

carlpett Punkte 11327

Ich las zufällig die sshd_config man-Seite, die nichts mit diesem Thema zu tun hat, die Option AcceptEnv :

AcceptEnv Gibt an, welche Umgebungsvariablen vom Client gesendet werden werden in das environ(7) der Sitzung kopiert werden. Siehe SendEnv in ssh_config(5), wie Sie den Client konfigurieren können. Beachten Sie, dass Umgebung - ronment passing nur für Protokoll 2 unterstützt wird. Variablen sind Variablen werden durch ihren Namen angegeben, der die Platzhalter Zeichen *' and ?'. Mehrere Umgebungsvariablen können getrennt werden durch Leerzeichen getrennt sein oder sich über mehrere AcceptEnv-Direktiven erstrecken. Sei gewarnt werden, dass einige Umgebungsvariablen dazu verwendet werden können zu umgehen. eingeschränkte Benutzerumgebungen zu umgehen. Aus diesem Grund sollte man darauf achten sollten Sie bei der Verwendung dieser Direktive Vorsicht walten lassen. Die Vorgabe ist, keine akzeptieren keine Umgebungsvariablen.

Vielleicht können Sie dies mit AcceptEnv: * ? Ich habe keine Box mit sshd zur Hand, aber probieren Sie es aus!

3voto

David Newcomb Punkte 10288

Sie sollten Folgendes verwenden set anstelle von env .

Aus dem bash-Handbuch:

Ohne Optionen werden der Name und der Wert jeder Shell-Variablen in einem Format angezeigt, das als Eingabe für das Setzen oder Zurücksetzen der aktuell gesetzten Variablen wiederverwendet werden kann.

Damit sind alle Probleme mit Semikolon und Backslash gelöst.

scp /path/to/script server.example.org:/another/path/
set > environment
scp environment server.example.org:/another/path/
ssh server.example.org "source environment; /another/path/script"

Wenn es Variablen gibt, die Sie nicht übermitteln möchten, können Sie sie mit einer Formel wie dieser herausfiltern:

set | grep -v "DONT_NEED" > environment

Sie könnten auch die ~/.bash_profile auf dem entfernten System, um das Umgebungsskript auszuführen, wenn Sie sich anmelden, damit Sie das Umgebungsskript nicht explizit ausführen müssen:

ssh server.example.org "/another/path/script"

2voto

Lynch Punkte 8624

Das Problem ist, dass ; markieren das Ende Ihres Befehls. Du musst ihnen entkommen:

Versuchen Sie es mit diesem Befehl:

env | sed 's/;/\\;/g'

Update : Ich habe den Befehl auf einem entfernten Rechner getestet und er hat bei mir funktioniert:

var1='something;using semicolons;'
ssh hostname "`env | sed 's/;/\\\\;/g' | sed 's/.*/set &\;/g'` echo \"$var1\""

Ich entkomme doppelt ; whit \\\\; und dann verwende ich eine andere sed-Substitution, um Variablen in Form von set name=value; . Auf diese Weise wird sichergestellt, dass alle Variablen auf dem entfernten Host korrekt gesetzt werden, bevor der Befehl ausgeführt wird.

1voto

carlpett Punkte 11327

Wie wäre es, die Umgebung gleichzeitig hochzuladen?

scp /path/to/script server.example.org:/another/path/
env > environment
scp environment server.example.org:/another/path
ssh server.example.org "source environment; /another/path/script"

1voto

salva Punkte 9683

Perl als Retter in der Not:

#!/usr/bin/perl

use strict;
use warnings;

use Net::OpenSSH;
use Getopt::Long;

my $usage = "Usage:\n  $0 --env=FOO --env=BAR ... [user\@]host command args\n\n";

my @envs;
GetOptions("env=s" => \@envs)
    or die $usage;

my $host = shift @ARGV;
die $usage unless defined $host and @ARGV;

my $ssh = Net::OpenSSH->new($host);
$ssh->error and die "Unable to connect to remote host: " . $ssh->error;

my @cmds;
for my $env (@envs) {
    next unless defined $ENV{$env};
    push @cmds, "export " . $ssh->shell_quote($env) .'='.$ssh->shell_quote($ENV{$env})
}

my $cmd = join('&&', @cmds, '('. join(' ', @ARGV) .')');
warn "remote command: $cmd\n";
$ssh->system($cmd);

Und es wird nicht kaputt gehen, wenn Ihre Umgebungsvariablen komische Dinge wie Anführungszeichen enthalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X