I'm trying to run a bash script using shell_exec but It doesnt seem to work. (Nothing seems to happen) I'm using nginx and the latest php5-cgi. Heres what the php file looks like:
<?php
$startserver = "./startserver.sh";
$startserver = shell_exec($startserver);
$getprocess = "pidof hlds_amd";
$pid = shell_exec($getprocess);
$fh = fopen('closeserver.sh', 'w');
$command = "kill -9 $pid";
fwrite($fh, $command);
fclose($fh);
$string = "at -f closeserver.sh now + 1 hour";
$closer = shell_exec($string);
?>
and this is what the bash script looks like:
#!/bin/bash
cd /home/kraffs/srcds
./hlds_run -game cstrike -autoupdate +maxplayers 12 +map de_dust2 > hlds.log 2>&1 &
Theres no errors in the phpscript and the file gets created just fine but $startserver doesnt seem to get executed and $pid is empty. Did I miss something in the php file or do I need to change permissions for an user? Thanks for your help.
replace shell_exec, with below function and try again
<?php
function runcmd($EXEC_CMD)
$handle = popen ($EXEC_CMD, 'r');
$output = "";
if ($handle) {
while(! feof ($handle)) {
$read = fgets ($handle);
$output .= $read;
}
pclose($handle);
}
return $output;
}
?>
Related
I am running a python script through my php. It works fine on console but returns null when I run it on browser.I even tried writing output to a file, but it doesn't return anything.
The php code is:
<?php
$y = "python Code.py";
$output = shell_exec($y);
if($output!=null){
echo $output;
}
else {
echo "No output";
}
$myfile = fopen("test.txt", "w") or die("Unable to open file!");
fwrite($myfile, $output);
fclose($myfile);
?>
$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;
#!/usr/bin/env python **is this in the first line of you python script?**
chmod +x /usr/custom/test.py
i want to run a command in console then 'echo' it via a log file. i wrote following code. but it doesnt work. if i put command direct in 'popen' it waits first the page load..
what can be done ?
shell_exec("nohup $cmd > out.log 2>&1");
if( ($fp = popen("tail out.log" , "r")) ) {
while( strpos($txt, "FINISH") == false){
$txt = fread($fp, 1024);
echo $txt;
flush();
}
}
Ealier I used function in a seperate file that could be call by script for cron.
function processExists($file = false) {
$exists = false;
$file = $file ? $file : basename(__FILE__);
$command = "ps -ef | grep -v grep | grep $file";
exec($command, $pids);
if (count($pids) > 1) {
$exists = true;
}
return $exists;
}
It could be executed from any php script as:
if (processExists(basename(__FILE__))) {
echo 'Process in already running ';
exit(0);
}
For some reason it doesn't work in Debian6.
Now I add in the beginning of every script:
$fh = fopen(__FILE__, 'r');
if (!flock($fh, LOCK_EX | LOCK_NB)) {
echo 'Script is already running!!!' . "\n";
exit(0);
}
It causes duplication of code in every script I tried to create function in a seperate file to call from any php script when neccessary, for example something like this:
function stopIfRunning($file)
{
$fh = fopen($file, 'r');
if(!flock($fh, LOCK_EX | LOCK_NB)) {
echo 'Script is already running!!!' . "\n";
exit(0);
}
}
And calling from php script:
stopIfRunning(__FILE__);
But it doesn't work in this case. Could you please explain why it doesn't work in this case?
If you need to make sure the service is running, use Daemontools or Monit.
And personally, I would use plain Bash, not PHP, if custom implementation needed.
BTW, you can easily debug your ps command in terminal.
FILE it is name of running file.
stopIfRunning(__FILE__);
function stopIfRunning($file)
{
$fh = fopen($file, 'r');
....
}
Here you tried open this executed file for lock.
It seems the problem is with $fh on stopIfRunning function. If the file with with functiona changed it with:
$fh = null;
function stopIfRunning($file)
{
global $fh;
echo $file, "\n";
$fh = fopen($file, 'r');
if (!$fh) {
echo 'Failed to open file', "\n";
}
if(!flock($fh, LOCK_EX | LOCK_NB)) {
echo 'Script is already running!!!' . "\n";
exit(0);
}
}
And call it in the file that should be launched using cron:
stopIfRunning(__FILE__);
Here global variable is used, which is not good. It would be great if somebody suggest a solution without global variable.
I have this shell program that I want to execute by php. The problem is that it can potentially take a long time, and as of that I need it to have real-time updating to the user's browser.
I read that I may need to use popen() to do that, but I am sort of (ok, I really am :P) a PHP noob and can't figure out how I may be able to do it.
Would appreciate any help!
if( ($fp = popen("your command", "r")) ) {
while( !feof($fp) ){
echo fread($fp, 1024);
flush(); // you have to flush buffer
}
fclose($fp);
}
there is a dirty easy option
`yourcommand 1>&2`;
redirecting the stdout to the stderr.
there are two possible behaviors:
Non Block, where you need to do something else between flushs (#GameBit show how to do it).
With Block, where you wait until the called command finish, in this case look passthru function
I used this solution. It works fine for me.
$commandString = "myexe";
# Uncomment this line if you want to execute the command in background on Windows
# $commandString = "start /b $commandString";
$exec = popen($commandString, "r");
# echo "Async Code Test";
while($output = fgets($exec, 2048))
{
echo "$output <br>\n";
ob_flush();
flush();
}
pclose($exec);
try this code (tested on Windows machine + wamp server)
header('Content-Encoding: none;');
set_time_limit(0);
$handle = popen("<<< Your Shell Command >>>", "r");
if (ob_get_level() == 0)
ob_start();
while(!feof($handle)) {
$buffer = fgets($handle);
$buffer = trim(htmlspecialchars($buffer));
echo $buffer . "<br />";
echo str_pad('', 4096);
ob_flush();
flush();
sleep(1);
}
pclose($handle);
ob_end_flush();
I invoked a php file by exec() doing this :
<?php
$cmd = "php -q nah.php";
exec($cmd);
echo "lalal";
?>
and the nah.php has this :
<?php
echo "yaya";
sleep(3);
?>
It does sleep for 3 seconds but the file can echo out to the command.
How can I do echo the output from nah.php
If you want to capture the output of another process, then you can use backticks
$output=`command line`;
or capture it with exec()
exec('command line', $output);
However, both of these techniques only give the output when the external process has run to completion. If you want to grab the output as it happens, you can use popen (or proc_open for more control), e.g. something like this
$handle = popen('command line 2>&1', 'r');
while (!feof($handle))
{
$read = fread($handle, 2096);
echo $read;
}
pclose($handle);
The 2>&1 at the end of the command line is a handy idiom if running within a shell like bash. It redirects stderr to stdout, so any errors the command generates will be returned to PHP. There are more advanced ways to capture stderr, this just makes it easy.
Change your first script to:
<?php
$cmd = "php -q nah.php";
echo `$cmd`;
echo "lalal";
exec() creates a new console and executes the php file there, it returns the output in an array (One element per line return) that is passed in as a second argument. So if you change your code to:
<?php
$output = array();
$cmd = "php -q nah.php";
exec($cmd, $output);
$lines = count($output);
for($i = 0; $i < $lines; $i++)
echo $output[$i];
echo "lalal";
?>