Howto execute shell command and display content on a webpage while running? - php

I am trying to start a cd rip with cdparanoia -E 1 and want to process the progress bar.
The sample code does output content in browser but just after everything is finished. If its called in cli content is displayed directly.
$cmd = 'cdparanoia -e 1';
#ob_end_clean();
$proc = popen($cmd, 'r');
while (!feof($proc))
{
echo fread($proc, 4096).'<br>';
flush();
#ob_flush();
}
My env is debian with nginx 1.6.2 and php5-fpm 5.6.17.

Related

Execute shell command and get live output

I'm trying to execute the following command from PHP, the problem is that I tried "PING", "netstat -a" and "ls", all of them worked fine and I got the output.
Wpscan is a Wordpress bug scanner, it's written in ruby, I installed it in the server and used this command to make it executable from anywhere
sudo ln -s /home/ubuntu/wpscan/wpscan.rb /usr/local/bin/wpscan
As you can see I tried the same command on the shell and it is working fine. I don't know what's the problem with the PHP code.
wpscan command
$cmd = 'wpscan -u www.google.com';
while (# ob_end_flush()); // end all output buffers if any
$proc = popen($cmd, 'r');
echo '<pre>';
while (!feof($proc))
{
echo fread($proc, 4096);
# flush();
}
echo '</pre>';
?>
Update:
I just put the following "2>&1" at the end of the command and I got the following error:
/home/ubuntu/wpscan/lib/common/common_helper.rb:6:in home': couldn't find HOME environment -- expanding~' (ArgumentError)
from /home/ubuntu/wpscan/lib/common/common_helper.rb:6:in '
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:inrequire'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in require'
from /home/ubuntu/wpscan/lib/wpscan/wpscan_helper.rb:3:in'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in require'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:inrequire'
from /usr/local/bin/wpscan:8:in `
Update2:
I just checked the users of PHP script and shell.
PHP: www-data
Shell: ubuntu

Bash output in web browser

I made a script in bash for getting pings into a file.
#!/bin/sh
echo "Starting script"
echo "Working.."
while true; do
DATE=$(date)
PING=$(ping -c 1 google.pl | tail -1| awk '{print $4}' | cut -d '/' -f 2)
echo "$DATE Ping: $PING" >> logs/ping.txt
sleep 5000
done
But due to lack of free space i changed echo "$DATE Ping: $PING" >> logs/ping.txt to just echo "$DATE Ping: $PING" to recive every line in cmd, and it worked
But still the main idea is to run the scipt through the web browser and display its output. (i can run it tho but i have no idea how to show echo output in a browser)
You can call the bash script from php using:
exec('myscript.sh');
And then open the ping.txt using:
$myFile = "ping.txt";
$fh = fopen($myFile, 'r');
$theData = fread($fh, filesize($myFile));
fclose($fh);
echo $theData;
Without text file:
$ping = shell_exec('myscript.sh');
echo "<pre>$ping</pre>";
With a bit of ajax and using Net_Ping you could have a page that updates in near-realtime.
Alternatively use shell_exec to run ping from inside your php and echo the output returned from it.
If you need to execute your bash script from PHP and display the output in a browser, then just use the shell_exec() PHP function
Example from php.net:
<?php
$output = shell_exec('/path/script-name-here');
echo "<pre>$output</pre>";
?>

Show real time wget output in a web page

I'm calling a shell script using shell_exec function of php where I'm downloading a file from another server to the server where this php page is hosted using wget command and sending a report to my page after completing the process. It works fine.
Here is my TestFile.php file
<?php
$output = shell_exec("sudo /home/user/myScript");
echo "<pre>$output</pre>";
?>
And my bash script myScript
#!/bin/sh
sudo wget -O /path/to/download/downloadfile http://example.com/TestFile.zip
But I want to show the real time progress of the wget operation on the webpage from where I'm calling the shell script. I want to show just the real time progress in percentage. On this way I'm able to send the progress of wget just in percentage to the webpage using this command
sudo wget -O /path/to/download/downloadfile http://example.com/TestFile.zip 2>&1 | grep -o "[0-9]\+%"
And, The output is like this
2%
4%
6%
8%
...
...
...
95%
97%
99%
100%
But this output is coming after completing the process. At the time of the process running the window doesn't show anything. But I don't want this.
I want the real time update of the process at the time of wget process running not after completing the command.
Could any one help me to solve the problem.
Thanks in advance.
Can't test it at the moment but something like this should work:
<?php
ob_start();
$descriptors = [
['pipe', 'r'],
['pipe', 'w'],
['pipe', 'w'],
];
$process = proc_open('wget blahblah', $descriptors, $pipes, '/tmp', []);
if(is_resource($process)) {
while ($line = fgets($pipes[1])) {
echo $line;
ob_flush();
}
}

How do I keep a websocket server running, even after I close the SSH terminal?

So, I am using Ratchet with PHP, and have currently uploaded a successful websocket example to my server.
It works after I go to SSH, and then just manually run "php bin/chat-server.php".
What I was wondering is that, in a commercial situation, how do I keep the chat server running?
Thanks.
Make a daemon.
If you are using symfony2, you can use the Process Component.
// in your server start command
$process = new Process('/usr/bin/php bin/chat-server.php');
$process->start();
sleep(1);
if ($process->isRunning()) {
echo "Server started.\n";
} else {
echo $process->getErrorOutput();
}
// in your server stop command
$process = new Process('ps ax | grep bin/chat-server.php');
$process->run();
$output = $process->getOutput();
$lines = preg_split('/\n/', $output);
// kill everything (there can be multiple processes if they are spawned)
$stopped = False;
foreach ($lines as $line) {
$ar = preg_split('/\s+/', trim($line));
if (in_array('/usr/bin/php', $ar)
and in_array('bin/chat-server.php', $ar)) {
$pid = (int) $ar[0];
posix_kill($pid, SIGKILL);
$stopped = True;
}
}
if ($stopped) {
echo "Server stopped.\n";
} else {
echo "Server not found. Are you sure it's running?\n";
}
If you are using native PHP, never fear, popen is your friend!
// in your server start command
_ = popen('/usr/bin/php bin/chat-server.php', 'r');
echo "Server started.\n";
// in your server stop command
$output = array();
exec('ps ax | grep bin/chat-server.php', &$output);
$lines = preg_split('/\n/', $output);
// kill everything (there can be multiple processes if they are spawned)
$stopped = False;
foreach ($lines as $line) {
$ar = preg_split('/\s+/', trim($line));
if (in_array('/usr/bin/php', $ar)
and in_array('bin/chat-server.php', $ar)) {
$pid = (int) $ar[0];
posix_kill($pid, SIGKILL);
$stopped = True;
}
}
if ($stopped) {
echo "Server stopped.\n";
} else {
echo "Server not found. Are you sure it's running?\n";
}
There are of course also other helpful PHP libraries for working with daemons. Googling "php daemon" will give you a lot of pointers.
The ratchet documentation has a deploy page. Did you checked it?
Old answer:
It may be a bad idea on a prod server (this is a personal assumption), but you can use the screen command to open a terminal, launch your daemon, then press Ctrl-A, Ctrl-D, and your terminal is still alive, opened in background. To reconnect to this terminal, connect back to your server and type screen -r.
This tutorial shows a really cool way of turning the WebSocket into a *nix Service to make it persist even when you close your SSH connection.
Basically you make a file /etc/init/socket.conf with the following contents
# Info
description "Runs the Web Socket"
author "Your Name Here"
# Events
start on startup
stop on shutdown
# Automatically respawn
respawn
respawn limit 20 5
# Run the script!
# Note, in this example, if your PHP script (the socket) returns
# the string "ERROR", the daemon will stop itself.
script
[ $(exec /usr/bin/php -f /path/to/socket.php) = 'ERROR' ] && ( stop; exit 1; )
end script
Blog Post:
http://blog.samuelattard.com/the-tutorial-for-php-websockets-that-i-wish-had-existed/
From the Ratchet Deployment page:
if you are running Ubuntu, fallow these steps:
install supervisor like this:
Installing Supervisor
configure ratchet webserver as a service program like this:
Supervisor Process Control | Supervisord Install & Usage
making a conf file in /etc/supervisor/conf.d/.conf and fill the conf exmple code from Ratchet Deployment page:
[program:ratchet]
command = bash -c "ulimit -n 10000; exec /usr/bin/php /absolute/path/to/ratchet-server-file.php)"
process_name = Ratchet
numprocs = 1
autostart = true
autorestart = true
user = root
stdout_logfile = ./logs/info.log
stdout_logfile_maxbytes = 1MB
stderr_logfile = ./logs/error.log
stderr_logfile_maxbytes = 1MB
run the following comands:
$ supervisorctl reread
$ supervisorctl update
and finally check if your service is running: $ supervisorctl
these are all the steps that should be added in Ratched Deployment tutorial.. but this approach may not be the best..
Start it in /etc/rc.d/rc for *nix servers. This should launch your PHP script whenever the server boots.
I don't actually know about how the industry does it, as I am just a programming/linux hobbyist and student right now, but that's the route I would go on a personal server.

What is linux equivalent of running a .bat file on windows from PHP using system()

I have a PHP script that runs a .bat file on my windows machine using
$result = system("cmd /C nameOfBatchFile.bat");
This sets some environmental variables and is used to call Amazon EC2 API from the command line.
How do I do the same from a Linux server? I have renamed my .bat file to a shell (.sh) and changed the script to use 'export' when setting env vars. I have tested by running the code from a putty terminal and it does what it should. So I know the commands in the script are good. How do I run this from PHP? I have tried running the same command as above with the new filename and I don't get any errors, or file not found etc but it doesn't appear to work.
Where do I start trying to solve this?
---------------------------------- UPDATE -------------------------------
Here is the PHP script that calls the shell file -
function startAmazonInstance() {
$IPaddress = "1.2.3.4"
$resultBatTemp = system("/cmd /C ec2/ec2_commands.sh");
$resultBat = (string)$resultBatTemp;
$instanceId = substr($resultBat, 9, 10);
$thefile = "ec2/allocate_address_template.txt";
// Open the text file with the text to make the new shell file file
$openedfileTemp = fopen($thefile, "r");
contents = fread($openedfileTemp, filesize($thefile));
$towrite = $contents . "ec2-associate-address -i " . $instanceId . " " . $IPaddress;
$thefileSave = "ec2/allocate_address.sh";
$openedfile = fopen($thefileSave, "w");
fwrite($openedfile, $towrite);
fclose($openedfile);
fclose($openedfileTemp);
system("cmd /C ec2/mediaplug_allocate_address_bytemark.sh");
}
And here is the .sh file - ec2_commands.sh
#!/bin/bash
export EC2_PRIVATE_KEY=$HOME/.ec2/privateKey.pem
export EC2_CERT=$HOME/.ec2/Certificate.pem
export EC2_HOME=$HOME/.ec2/ec2-api-tools-1.3-51254
export PATH=$PATH:$EC2_HOME/bin
export JAVA_HOME=$HOME/libs/java/jre1.6.0_20
ec2-run-instances -K $HOME/.ec2/privateKey.pem -C $HOME/.ec2/Certificate.pem ami-###### -f $HOME/.ec2/aws.properties
I have been able to run this file from the command line so I know that the commands work ok. When I had this working on windows there would be a delay as the instance started up and I could echo the results to the screen. Now there is no delay as if nothing is happening.
Put a hash-bang on the first line of your shell script.
#!/bin/bash
Then give it the executable flag.
$ chmod a+x yourshellscript
You can then call it from PHP with system.
$result = system("yourshellscript");
$result = system("/bin/sh /path/to/shellfile.sh");
Is script executable? If not, make it so:
$ chmod a+x script.sh # shell
system ("/path/to/script.sh"); // PHP
or launch it via interpreter:
system("sh /path/to/script.sh"); // PHP
Is interpreter specified in shell script (ie. #!/bin/sh line)?
have you tried shell_exec() ?

Categories