Start · Sprachen · PHP · Referenz · ssh2_exec

ssh2_exec

Funktion

Führt einen Befehl auf einem entfernten SSH-Server aus und gibt einen Stream zurück, über den die Ausgabe gelesen werden kann.

seit PHP 0.9.0 Kategorie: http

Signatur

ssh2_exec(resource $session, string $command, string $pty = null, array $env = null, int $width = 80, int $height = 25, int $width_height_type = SSH2_TERM_UNIT_CHARS): resource|false

Beschreibung

ssh2_exec() ist Teil der SSH2-Erweiterung (PECL) und ermöglicht es, einen einzelnen Befehl auf einem entfernten Server über eine bestehende SSH-Verbindung auszuführen. Der Rückgabewert ist ein Stream-Ressource-Handle, über das die Standard-Ausgabe (stdout) des Befehls gelesen werden kann.

Um auch die Fehlerausgabe (stderr) zu lesen, muss nach dem Aufruf mit ssh2_fetch_stream() und der Konstante SSH2_STREAM_STDERR ein separater Stream abgerufen werden. Beide Streams sollten blockierend oder nicht-blockierend gesetzt werden, bevor man von ihnen liest – andernfalls kann es zu Deadlocks kommen.

Die Funktion eignet sich für typische Anwendungsfälle wie Remote-Administration, automatisierte Deployments oder das Abrufen von Systeminformationen von entfernten Servern. Im Gegensatz zu einer SSH-Shell (ssh2_shell()) öffnet ssh2_exec() keinen interaktiven Kanal, sondern führt genau einen Befehl aus und schließt den Kanal danach.

Wichtig: Die Erweiterung ext/ssh2 ist eine PECL-Erweiterung und nicht standardmäßig in PHP enthalten. Sie muss separat installiert werden (z. B. via pecl install ssh2).

Parameter

Name Typ Default Beschreibung
$session Pflicht resource Eine aktive SSH-Verbindungs-Ressource, die zuvor mit ssh2_connect() erstellt und authentifiziert wurde.
$command Pflicht string Der auf dem entfernten Server auszuführende Shell-Befehl als Zeichenkette.
$pty string null Optionaler Terminaltyp (z. B. 'vt102'). Wenn angegeben, wird ein Pseudo-Terminal (PTY) angefordert. Für einfache Befehle in der Regel null lassen.
$env array null Assoziatives Array mit Umgebungsvariablen, die für die Ausführung des Befehls gesetzt werden sollen (z. B. ['PATH' => '/usr/bin']).
$width int 80 Breite des virtuellen Terminals in Zeichen (oder Pixeln, abhängig von width_height_type).
$height int 25 Höhe des virtuellen Terminals in Zeilen (oder Pixeln, abhängig von width_height_type).
$width_height_type int SSH2_TERM_UNIT_CHARS Gibt an, ob width und height in Zeichen (SSH2_TERM_UNIT_CHARS) oder Pixeln (SSH2_TERM_UNIT_PIXELS) gemessen werden.

Rückgabewert

Typ
resource|false
Beschreibung
Gibt bei Erfolg eine Stream-Ressource zurück, über die die Standardausgabe des Befehls gelesen werden kann. Im Fehlerfall wird false zurückgegeben.

Beispiele

Einfachen Befehl auf Remote-Server ausführen und Ausgabe lesen

<?php
// Verbindung aufbauen
$connection = ssh2_connect('example.com', 22);
if (!$connection) {
    die('Verbindung fehlgeschlagen.');
}

// Authentifizierung mit Benutzername und Passwort
if (!ssh2_auth_password($connection, 'deploy', 'geheimespasswort')) {
    die('Authentifizierung fehlgeschlagen.');
}

// Befehl ausführen
$stream = ssh2_exec($connection, 'uname -a');
if ($stream === false) {
    die('Befehl konnte nicht ausgeführt werden.');
}

// Stream auf blockierend setzen und Ausgabe lesen
stream_set_blocking($stream, true);
$output = stream_get_contents($stream);
fclose($stream);

echo 'Ausgabe: ' . $output;
Ausgabe: Linux example.com 5.15.0-76-generic #83-Ubuntu SMP Thu Jun 15 19:16:32 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Befehl ausführen und Fehlerausgabe (stderr) separat erfassen

<?php
$connection = ssh2_connect('example.com', 22);
ssh2_auth_password($connection, 'deploy', 'geheimespasswort');

// Befehl mit einem absichtlichen Fehler ausführen
$stream = ssh2_exec($connection, 'ls /nicht/vorhanden 2>&1 || true');

if ($stream === false) {
    die('Ausführung fehlgeschlagen.');
}

// stderr-Stream holen
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);

// Beide Streams auf blockierend setzen
stream_set_blocking($stream, true);
stream_set_blocking($errorStream, true);

$stdout = stream_get_contents($stream);
$stderr = stream_get_contents($errorStream);

fclose($errorStream);
fclose($stream);

echo 'STDOUT: ' . $stdout . PHP_EOL;
echo 'STDERR: ' . $stderr . PHP_EOL;
STDOUT: ls: cannot access '/nicht/vorhanden': No such file or directory STDERR:

// Wichtig · Fallstricke

Sicherheitshinweis: Benutzereingaben dürfen niemals ungeprüft in den $command-Parameter eingefügt werden, da dies zu Remote Code Execution führen kann. Eingaben sollten mit escapeshellarg() oder einem Whitelist-Ansatz abgesichert werden.

Deadlock-Gefahr: Das Lesen von stdout und stderr in der falschen Reihenfolge kann zu einem Deadlock führen, wenn der Remote-Prozess auf das Leeren eines Puffers wartet. Setze beide Streams auf blockierend und lies sie nacheinander, oder nutze stream_select() für nicht-blockierendes Lesen.

Befehlsende erkennen: Das Stream-Handle wird erst geschlossen, wenn der Remote-Befehl abgeschlossen ist. stream_get_contents() blockiert so lange, bis der Prozess beendet ist – bei lang laufenden Prozessen sollte ein Timeout berücksichtigt werden.

Die SSH2-Erweiterung ist eine PECL-Erweiterung und erfordert libssh2 als Systembibliothek. Alternativ kann die reine PHP-Bibliothek phpseclib verwendet werden, die keine PECL-Installation benötigt.