Wie starte ich das Programm per PHP mit SSH2?

2 Antworten

>>Er führt den Befehl "csgo-server @training1 restart" auch aus, nur bricht er diesen wieder ab.

Wirft er eine Fehlermeldung?

>>Kann ich den Befehl irgendwie länger ausführen lassen oder gibt es dazu noch andere Lösungswege?

Du kannst via nohup Signal 1 umgehen und mit & in den Hintergrund schieben. Ob das Sinn hat steht auf einem anderen Blatt.

Bsp:

$restart = "nohup csgo-server @training1 restart &>/dev/null &";
SebastianJustin 
Fragesteller
 29.04.2018, 17:02
$notiz = '';

if(isset($_POST['restart'])) {

// Run a command that will probably write to stderr (unless you have a folder named /hom)

$stream = ssh2_exec($connection, $restart);

$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);

// Enable blocking for both streams

stream_set_blocking($errorStream, true);

stream_set_blocking($stream, true);

// Whichever of the two below commands is listed first will receive its appropriate output. The second command receives nothing

$notiz = "Output: " . stream_get_contents($stream);

$notiz .= " Error: " . stream_get_contents($errorStream);

// Close the streams     

fclose($errorStream);

fclose($stream);

}

Das zeigt er mir in der $notiz an, den unwichtigen kram davor habe ich weggelassen.

**Instance @training1** started successfully! Use csgo-server @training1 console to enter the game's console. 

Error: open terminal failed: not a terminal
0
Kieselsaeure  29.04.2018, 17:18
@SebastianJustin

Braucht der denn wirklich ein Terminal? Gibts da keinen Schalter um das zu umgehen?

Wenn nein: villeicht wäre screen oder tmux die Lösung.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:27
@Kieselsaeure

Der Server wird mit tmux gestartet, aber das sieht so kompliziert aus, dass ich da nicht durchsteige.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:15

"$restart = "nohup csgo-server @training1 restart &>/dev/null &";"

Funktioniert schon mal nicht.

0

Füg mal an die letzte Zeile ein "sleep(10);" an. Berichte dann, ob es (nach 10 Sekunden) geklappt hat. Wenn ja, dann hätten wir schonmal eine sehr ekelhafte Lösung gefunden und könnten gezielt eine bessere Lösung finden :-)

SebastianJustin 
Fragesteller
 29.04.2018, 16:09

Das änder nichts. Vielleicht ist dies ja von Vorteil:

root@h2755339:~# csgo-server @training1 restart

**INFO:**
    Instance @training1 is already stopped.

Starting Instance @training1 ...
Loading gamemode-specific settings for gamemode **competitive** ...
Generating configuration files ...
    mapcycle.txt
    cfg/autoexec.cfg
    cfg/server.cfg
Generating launch arguments ...
**INFO:**
    The launch command is:
        /root/csgo@training1/srcds_run -game csgo -console -usercon
        -tickrate 128 +sv_setsteamaccount 271B8C10CFD71C8361DCF24909A86A98
        -port 27415 +game_type 0 +game_mode 1 +mapgroup mg_active +map
        de_cache -nobots -maxplayers 10
[detached (from session csgo@training1)]
**SUCCESS:**
    **Instance @training1** started successfully!

    Use **csgo-server @training1 console** to enter the game's
    console.
root@h2755339:~# 

So sieht der normale Ablauf bei PuTTy aus.

Kann ich denn irgendwo die ausgehenden Logs von der php sehen?

0
verreisterNutzer  29.04.2018, 16:12
@SebastianJustin

Probiere mal statt deiner letzten Zeile (die mit $notiz) folgenden Quellcode. Ich hoffe da sind keine Syntaxfehler, ich habe hier keinen gescheiten Editor zur Hand.

$notiz = '';

if(isset($_POST['restart'])) {

// Run a command that will probably write to stderr (unless you have a folder named /hom)

$stream = ssh2_exec($connection, $restart);

$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);

// Enable blocking for both streams

stream_set_blocking($errorStream, true);

stream_set_blocking($stream, true);

// Whichever of the two below commands is listed first will receive its appropriate output. The second command receives nothing

$notiz = "Output: " . stream_get_contents($stream);

$notiz .= " Error: " . stream_get_contents($errorStream);

// Close the streams     

fclose($errorStream);

fclose($stream);

}

echo $notiz;

0
verreisterNutzer  29.04.2018, 16:15
@verreisterNutzer

Eine weitere Idee wäre, dass du zwei Befehle an den Server schickst. Einen zum Stoppen des Servers und einen zweiten, der dann den Befehl aus den Logs benutzt: "/root/csgo@training1/srcds_run -game csgo -console -usercon -tickrate 128 +sv_setsteamaccount 271B8C10CFD71C8361DCF24909A86A98-port 27415 +game_type 0 +game_mode 1 +mapgroup mg_active +map de_cache -nobots -maxplayers 10"

0
SebastianJustin 
Fragesteller
 29.04.2018, 16:22
@verreisterNutzer
Instance @training1** started successfully! Use **csgo-server @training1 console** to enter the game's console.  Error: open terminal failed: not a terminal

Das ist der Output. Den ersten Teil habe ich weggelassen.

0
SebastianJustin 
Fragesteller
 29.04.2018, 16:24
@verreisterNutzer

Das mit deiner anderen Idee wird nicht wirklich funktionieren, da er die Configs zu dem Server von wo anders zieht, welches das Script dazu liest.

0
verreisterNutzer  29.04.2018, 16:31
@SebastianJustin

Okay ich glaube ich habe eine Vermutung, was das Problem ist.

Der Befehl "csgo-server @training1 restart" öffnet ein weiteres Terminal, mit dem er arbeitet. Das funktioniert in putty ohne Probleme. Mit dem PHP-Befehl ssh2 geht das jedoch nicht, weil wir hier nur einen Befehl reinschieben und die Antwort durch ein Stream geschickt wird. Ein unter-Terminal scheint nicht zu funktionieren. Daher kommt die Fehlermeldung "open terminal failed: not a terminal"

Was mich verwirrt ist die Erfolgsmeldung am Anfang. Da steht ja noch was von "started successfully!".

0
SebastianJustin 
Fragesteller
 29.04.2018, 16:32
@verreisterNutzer

Das ist richtig, in PuTTy selbst wird von alleine aber auch nichts Augenscheinliches geöffnet was mich ebenfalls verwirrt.

0
SebastianJustin 
Fragesteller
 29.04.2018, 16:36
@verreisterNutzer

Oh, ja das stimmt.
Wenn ich den Server mit ""/root/csgo@training1/srcds_run -game csgo..." starten würde, dann würde nach der Schließung der Sitzung der Server abstürzen also ist sowas wie screen unumgänglich.

0
verreisterNutzer  29.04.2018, 16:36
@verreisterNutzer

Ich hätte ein paar Ideen wie man das umgehen könnte. Aber das sind hässliche Workarounds. Beispielsweise mit "Screen" selbst ein unterterminal starten, in dem ein Script mit endlosschleife läuft. Das Script fragt alle halbe minute ab, ob an einem bestimmten Ort eine textdatei liegt. Wenn nein, passiert nichts. Wenn ja, dann wird die textdatei gelöscht und der csgo server mit dem funktionierenden Befehl restartet.

Eine textdatei an einer bestimmten Stelle zu erstellen sollte ja mit ssh2 nicht so das problem sein. Ich glaube das geht schon mit "touch ~/file.txt"

0
verreisterNutzer  29.04.2018, 16:48
@SebastianJustin

Stimmt. Sauber wäre es wenn man sich mit screen besser auskennen würde. Bestimmt gibt es eine Möglichkeit einen Befehl in einen screen zu senden, ohne ihn direkt betreten zu müssen.

Zudem frage ich mich, ob "csgo-server @training1 restart" in einer screen session funktionieren würde. Wenn ja, dann könnte man über PHP diesen Befehl in die screen session absetzen.

0
SebastianJustin 
Fragesteller
 29.04.2018, 16:58
@verreisterNutzer

Quasi "screen -r <name> && csgo-server @training1 restart"?
Ich kann das gleich mal testen, klingt aber ein wenig Paradox ein terminal in nem screen zu starten.

0
verreisterNutzer  29.04.2018, 17:08
@SebastianJustin

Das sollte nicht funktionieren. Der zweite Befehl wird entweder parallel oder danach ausgeführt. Bin mir nicht sicher. Aber auf keinen Fall in der Screen Session.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:16
@verreisterNutzer
"screen -dmS <screen name> && screen -S <screen name> -X stuff '<CMD>\n'"

Das hätte ich gefunden.

Ich schau erstmal ob das in screen überhaupt möglich ist.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:21
@SebastianJustin

Frech :D Das funktioniert einfach...

screen -dmS csgo && screen -S csgo -X stuff 'csgo-server @training1 start\n'

Jetzt muss ich nur noch den screen wieder schließen, damit der nicht tausende davon erstellt, der screen wird quasi gar nicht benutzt, der detached das sofort, also der Server läuft ohne den screen auch weiter. Wie cool ist das denn? :D

0
verreisterNutzer  29.04.2018, 17:34
@SebastianJustin

Super! Dann läuft csgo irgendwie als Dienst. Interessant.

Ich nehme an das Schließen wirst du aber als extra ssh2-Befehl machen müssen, nachdem stream_get_contents im PHP durchgelaufen ist. Sonst schließt du es bestimmt zu früh.

0
verreisterNutzer  29.04.2018, 17:39
@verreisterNutzer

Und noch ein Kommentar am Rande, da wir gerade bei schöner Programmierung sind. Den root-user mit Passwort in das Script zu schreiben wäre eine very bad practice und sehr hässlich.

Normalerweise deaktiviert man in openssh auch den ssh Zugang des root-servers komplett. Du verbindest dich mit einem normalen user und su (oder sudo) bei bedarf in root-Rechte.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:44
@verreisterNutzer

Habe das jetzt wieder kleiner gemacht:

$restart = "screen -dmS csgo && screen -S csgo -X stuff 'csgo-server @training1 restart\n'";
$restart2 = "screen -X -S csgo kill";

if(isset($_POST['restart'])){
	ssh2_exec($connection, $restart2);
	$notiz = 'Server wird neu gestartet.';
	while(5);
	ssh2_exec($connection, $restart);
}

Aber egal wie ich es dreh und wende, er killt den screen einfach nicht. Über einen manuellen Button killt er ihn schon, nur möchte ich für beides ja nur einen benutzen.

Was meinst du "Den root-user mit Passwort in das Script zu schreiben" damit?

0
verreisterNutzer  29.04.2018, 17:49
@SebastianJustin

while(5) kenne ich gar nicht. O.o Ist das das gleiche wie Sleep(5)?

Steht in deinem Script nicht irgendwo Benutzername und Passwort des Root users? Wenn du über SSH eine Verbindung aufbaust wird das doch benötigt.

0
SebastianJustin 
Fragesteller
 29.04.2018, 17:52
@verreisterNutzer

MAAAAAN, wo habe ich denn jetzt dieses while() her? xD (Das war doch in C++?)

include("sshverbindung.php");

sshverbindung.php:

<?php
$server   = "domain"; 
$username = "root"; 
$password = "passwort"; 
?>

Jop, ich verbinde mich da mit dem root, mit dem mache ich leider alles...

0
verreisterNutzer  29.04.2018, 18:00
@SebastianJustin

Ich hoffe dein Passwort ist extrem gut. Sonst hast du da bald einen Spambot auf deiner Maschine :-D

Schöner wäre du würdest einen neuen User machen. Mit adduser geht das ganz einfach.

adduser csgoadmin

Der fragt dann noch ein paar mehr oder weniger wichtige Sachen wie z.B. Passwort ab und dann hast du einen anderen User, den du benutzen kannst.

Wenn du dann in /etc/ssh/sshd_config den Eintrag PermitRootLogin auf no setzt, und mit /etc/init.d/sshd restart openssh neu startest, darf der root sich auch nicht mehr verbinden.

Ich bin mir allerdings gar nicht mal sicher, ob ein normaler User den CSGO Server neu starten dürfte. Ggf. nur, wenn er ihn selbst auch gestartet hat.

0
verreisterNutzer  29.04.2018, 18:02
@SebastianJustin

Und in der Version, bei der PHP blockt bis alles fertig ist (stream_set_blocking)? Das ist, wenn auch länger, definitiv die schönere Variante als mit einem Sleep.

0
SebastianJustin 
Fragesteller
 29.04.2018, 18:20
@SebastianJustin

Ich hab keine Lust mehr, der cs Server möchte einfach nicht mehr starten... Habe den kompletten root schon neu hochgefahren...

0
verreisterNutzer  29.04.2018, 18:21
@SebastianJustin

Diesen Frust kenne ich. Ich glaube aber da kann ich dir leider nicht helfen... Gibt es wenigstens eine aussagekräftige Fehlermeldung?

0
SebastianJustin 
Fragesteller
 29.04.2018, 18:28
@SebastianJustin

Ich will da jetzt auch nicht wieder Stundenlang suchen, ich baller da einfach Heute Nacht wieder nen Back-Up von gestern rauf, dann sollte alles wieder klappen. Genug für Heute :D

0
SebastianJustin 
Fragesteller
 30.04.2018, 15:12
@SebastianJustin
$restart = "screen -dmS csgo && screen -S csgo -X stuff 'csgo-server @training1 restart\n'";
$restart2 = "screen -X -S csgo kill";

if(isset($_POST['restart'])){
	ssh2_exec($connection, $restart2);
	$notiz = 'Server wird neu gestartet.';
	sleep(5);
	ssh2_exec($connection, $restart);
}

So geht das nun doch.

Habe einfach nen neuen Server gemacht, keine Ahnung warum der andere nicht mehr funktioniert hat :D

0