Autor Zpráva
ForestCZE
Profil
Zdravím, potřeboval bych prosím pomoct. Mám v PHP:

exec("cd /home/steam/csgo; screen ./startup.sh");

Mělo by to spustit ten soubor startup.sh, ale bohužel nic.

Jen tak na zkoušku (jestli funguje exec) jsem zkusil:

exec("cd /home/steam/csgo; touch test.txt");

A exec funguje - vytvoří to soubor v té složce.

Složky v cestě /home/steam/csgo mají práva na 777, soubor startup.sh taktež. Jinak v tom startup.sh mám:

#!/bin/sh
./srcds_run -parametr1 -parametr2 -parametr3...

A soubor srcds_run má také práva na 777.

Děkuji předem za každou dobrou radu :)
xaverista
Profil
ForestCZE:
Zdravím, co takhle zkusit spouštět sh pomocí zadání absolutní cesty?

exec("screen /home/steam/csgo/startup.sh");
TomášK
Profil
xaverista
To nebude fungovat bez dalších úprav, uvnitř skriptu se odkazuje na lokální soubor.

ForestCZE
Myslím si, že problém je spuštění screenu bez terminálu. Najdi si, jak zjistit STDOUT a STDERR pro exec, tam zřejmě najdeš chybovou hlášku "Must be connected to a terminal."
Keeehi
Profil
ForestCZE:
Jsou minimálně dvě řešení.
exec("cd /home/steam/csgo && screen ./startup.sh");
nebo
chdir('/home/steam/csgo');
exec("screen ./startup.sh");
chdir(__DIR__);
TomášK
Profil
Keeehi
Pokud funguje ten příklad s touch test.txt, tak není problém v tom, že jsou předané dva příkazy ani se změnou adresáře.
Keeehi
Profil
TomášK:
Špatně jsem to četl, myslel jsem, že touch nefunguje :)
ForestCZE
Profil
TomášK:
Myslím si, že problém je spuštění screenu bez terminálu. Najdi si, jak zjistit STDOUT a STDERR pro exec, tam zřejmě najdeš chybovou hlášku "Must be connected to a terminal."

Omlouvám se, ale s tím STDOUT a STDERR se nechytám. Ve screenu asi chyba nebude, jelikož když to spustím normálně v terminálu, běží to, změní se mi status a tlačítko na webu, takže to zkusím alespoň vypnout, ale příkaz pkill také nefunguje, což je mi ještě divnější.
TomášK.
Profil *
Koukni se do dokumentace pro exec, jak se dá zachytit výstup. V diskuzi tam i někdo tvrdí, že funguje přesměrování stderr na stdout pomocí 2>&1 a jeho zachycení.

Screen potřebuje terminál. Pokud ho spustíš z terminálu, tak terminál k dispozici má. Pokud ho spustíš přes exec, tak zřejmě ne. Aneb to, že to funguje v terminálu, nic moc neznamená.

ssh server screen
Must be connected to a terminal.
ForestCZE
Profil
TomášK.:
Aneb to, že to funguje v terminálu, nic moc neznamená.
Špatně jsi mě pochopil. Já jsem psal, že když to pustím přes terminál (putty), abych to mohl zkusit alespoň killnout, tak to taky nejde. A pkill screen nemá.
TomášK.
Profil *
Máš pravdu, myslel jsem, že argumentuješ tím, že to v terminálu běží. pkill tipuju selže na právech. php zřejmě běží pod jiným uživatelem, než pod kterým jsi spustil screen nebo ten skript, a tedy nemá právo ho zabít.

Možná půjde screen spustit v terminálu a vhodnými parametry se k němu z php připojit. Lepší přístup pro to, co děláš, je napsat si službu (máš-li systemd, pak viz unix.stackexchange.com/questions/15348/writing-basic-systemd-service-files, jinak se koukni do /etc/init.d/) a pak z php volat systemctl start cs-server resp. systemctl stop cs-server
ForestCZE
Profil
Takže nová situace :D

Zkusil jsem si vytvořit jiný soubor.sh, ve kterém jsem zavolal touch test.txt a ten soubor to v pohodě vytvoří. Chyba je teda nejspíš v tom screenu, který tady celou dobu řešíme, že potřebuje připojení k terminálu.

Poupravil jsem celý exec následovně:

exec("cd /home/steam/csgo; screen -S csgo; ./startup.sh");

Skript se provede, ale zacyklí se (v procesech je vidět daný proces několikrát) a web spadne, pak jsem nucen rebootnout celý VPS.
TomášK
Profil
Když spustíš screen, tak běží, dokud ho někdo neukončíš. exec čeká než doběhne, což se nestane, a zůstane tam viset.
Jan Rippl
Profil
Asi budu za blba ale možná by bylo pro tento účel lepší shtml (SSI) spíše než PHP. něco jako <!--#exec cmd="ls -l" -->
ForestCZE
Profil
No tak už jsme to konečně s kolegou vyřešili.

Výsledek:

exec("cd /home/steam/csgo; screen -dm ./srcds_run -parametr1 -parametr2 ...);

A startup.sh šel do kelu :D

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0