I'm having trouble running the "exec" function in my PHP website. I am able to run it several times with an executable that just takes in a variable argument and returns some test message. However, when I use an executable that does some image processing, where I want to pass an image from the website that a user uploads as an argument, it does not seem to be executing the executable at all. I even have some cout commands in the executable to ensure its running, but these are not being displayed on the website. So I think that for some reason the php cannot run the executable? I am able to run it fine from my desktop...
Here's an example of the code that isn't working on my PHP website:
$imgtest1="/uploaded_files/me.jpg";
$imgtest2="/uploaded_files/clusteroutput.jpg";
$nosuppix = 400;
$noweight = 100;
$executabletest = exec("ImgProc $imgtest1 $nosuppix $noweight $imgtest2");
echo $executabletest;
Is there a way to debug or get an error output from the exec function? Is there something I'm missing when passing an image to the executable? The executable uses several DLL files which are in the same folder as the executable. Do they need to be packaged together for some reason? I apologize, but I really don't know what's left to test...
***Edit: I'm now able to get it to run if I write out all the code in the escapeshellcmd itself... how come I'm not able to just pass the variables?
$cmdinput = escapeshellcmd('SuperpixelsFinal "D:/WebPages/TALIA ART/TALIA ART/uploaded_files/me.jpg" 400 100 "D:/WebPages/TALIA ART/TALIA ART/uploaded_files/clusteroutput.jpg"');
For anyone else having this issue, it is because I was using escapeshellcmd when I should have used escapeshellarg for each individual string and then run the exec with double quotes using only variables like so:
$executabletest = exec("SuperpixelsFinal $imgtest1 $nosuppix $noweight $imgtest2");
ok, I know I'm doing something weird here but I gotta do it.
So my elixir program needs to run one PHP script and take the information from that script, but it never comes in. I can manually run the php script and it works fine. At the bottom of the script it says:
echo $avar->getPUId();
So it's printing it out to echo I guess. I get the data I need when I run it from a command line:
C:\PHP>php.exe "-f" "C:\pap.php" "613b8859"
37a69912
But when I run it from iex I get nothing:
iex(1)> System.cmd("C:\\PHP\\php.exe", ["-f", "C:\\pap.php", "613b8859"])
Terminate batch job (Y/N)? y
Now, if I mess up on the filename or something php will give me an error in response saying like:
iex(1)> System.cmd("C:\\PHP\\php.exe", ["-f", "C:\\pap321.php", "613b8859"])
{"Could not open input file: c:/pap123.php\n", 1}
...
so I know I can talk to PHP, and it can talk back to me with errors, but echo isn't caught by my elixir application that calls it apparently. Is there any other way I can grab the data as it comes out of the PHP script?
I used
https://github.com/alco/porcelain
result = Porcelain.shell("C:\\PHP\\php.exe -f C:\\pap.php 613b8859")
IO.inspect result.out
it worked great.
I have a server running on Linux that execute commands to 12 nodes (12 computers with Linux running in them). I recently downloaded PHP on the server to create web pages that can execute commands by opening a specific PHP file.
I used exec(), passthru(), shell_​exec(), and system(). system() is the only one that returns a part of my code. I would like PHP to act like open termainal command in linux and I cannot figure out how to do it!
Here is an example of what is happening now (Linux directly vs PHP):
When using linux open terminal command directly:
user#wizard:/home/hyperwall/Desktop> /usr/local/bin/chbg -mt
I get an output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
and additional code to send it to 12 nodes.
Now with PHP:
switch($_REQUEST['do'])
{ case 'test':
echo system('/usr/local/bin/chbg -mt');
break;
}
Output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
And stops! Anyone has an explanation of what is happening? And how to fix it? Only system displays part of the code the other functions display nothing!
My First thought is it can be something about std and output error. Some softwares dump some informations on std out and some in std error. When you are not redirecting std error to std out, most of the system calls only returns the stdout part. It sounds thats why you see the whole output in terminal and can't in the system calls.
So try with
/usr/local/bin/chbg -mt 2>&1
Edit:
Also for a temporary work through, you can try some other things. For example redirect the output to file next to the script and read its contents after executing the command, This way you can use the exec:
exec("usr/local/bin/chbg -mt 2>&1 > chbg_out");
//Then start reading chbg_out and see is it work
Edit2
Also it does not make sense why others not working for you.
For example this piece of code written in c, dumps a string in stderr and there is other in stdout.
#include <stdio.h>
#include<stdlib.h>
int main()
{
fputs("\nerr\nrro\nrrr\n",stderr);
fputs("\nou\nuu\nuttt\n",stdout);
return 0;
}
and this php script, tries to run that via exec:
<?php
exec("/tmp/ctest",&$result);
foreach ( $result as $v )
{
echo $v;
}
#output ouuuuttt
?>
See it still dumps out the stdout. But it did not receive the stderr.
Now consider this:
<?php
exec("/tmp/ctest 2>&1",&$result);
foreach ( $result as $v )
{
echo $v;
}
//output: errrrorrrouuuuttt
?>
See, this time we got the whole outputs.
This time the system:
<?php
echo system("/tmp/ctest 2>&1");
//output: err rro rrr ou uu uttt uttt
?>
and so on ...
Maybe your chbg -mt writes additional code to stderr instead of stdout? Try to execute your script inside php like this:
/usr/local/bin/chbg -mt 2>&1
The other responses are good for generic advice. But in this specific case, it appears you are trying to change your background on your desktop. This requires many special considerations because of 'user context':
First, your web server is probably running as a different user, and therefore would not have permissions to change your desktop.
Second, the program probably requires some environmental variables from your user context. For example, X programs need a DISPLAY variable, ssh-agent needs SSH_AGENT_PID and SSH_AUTH_SOCK, etc. I don't know much about changing backgrounds, but I'm guessing it involves D-Bus, which probably requires things like DBUS_SESSION_BUS_ADDRESS, KONSOLE_DBUS_SERVICE, KONSOLE_DBUS_SESSION, and KONSOLE_DBUS_WINDOW. There may be many others. Note that some of these vars change every time you log in, so you can't hard-code them on the PHP side.
For testing, it might be simpler to start your own webserver right from your user session. (i.e. Don't use the system one, it has to run as you. You will need to run it on an alternate port, like 8080). The web server you start manually will have all the 'context' it needs. I'll mention websocketd because it just came out and looks neat.
For "production", you may need to run a daemon in your user context all the time, and have the web server talk to that daemon to 'get stuff done' inside your user context.
PHP's system only returns the last line of execution:
Return Value: Returns the last line of the command output on success, and FALSE on failure.
You will most likely want to use either exec or passthru. exec has an optional parameter to put the output into an array. You could implode the output and use that to echo it.
switch($_REQUEST['do'])
{ case 'test':
exec('/usr/local/bin/chbg -mt', $output);
echo implode('\n', $output); // Could use <br /> if HTML output is desired
break;
}
I think that the result of execution, can changes between users.
First, try to run your PHP script directly into your terminal php yourScript.php
If it runs as expected, go to your Apache service and update it to run with your own credentials
You are trying to change the backgrounds for currently logged in users... While they are using the desktop. Like while I'm typing this message. I minimize my browser and 'ooh my desktop background is different'. Hopefully this is for something important like it turns red when the reactor or overheating.
Anyway to my answer:
Instead of trying to remotely connect and run items as the individual users. Setup each user to run a bash script (in their own account, in their own shell) on a repeating timer. Say every 10 minutes. Have it select the SAME file.. from a network location
/somenetworkshare/backgrounds/images/current.png
Then you can update ALL nodes (1 to a million) just by changing the image itself in /somenetworkshare/backgrounds/images/current.png
I wrote something a while ago that does just this -- you can run a command interpreter (/bin/sh), send it commands, read back responses, send more commands, etc. It uses proc_open() to open a child process and talk to it.
It's at http://github.com/andrasq/quicklib, Quick/Proc/Process.php
Using it would look something like (easier if you have a flexible autoloader; I wrote one of those too in Quicklib):
include 'lib/Quick/Proc/Exception.php';
include 'lib/Quick/Proc/Exists.php';
include 'lib/Quick/Proc/Process.php';
$proc = new Quick_Proc_Process("/bin/sh");
$proc->putInput("pwd\n");
$lines = $proc->getOutputLines($nlines = 10, $timeoutSec = 0.2);
echo $lines[0];
$proc->putInput("date\n");
$lines = $proc->getOutputLines(1, 0.2);
echo $lines[0];
Outputs
/home/andras/quicklib
Sat Feb 21 01:50:39 EST 2015
The unit of communication between php and the process is newline terminated lines. All commands must be newline terminated, and all responses are retrieved in units of lines. Don't forget the newlines, they're hard to identify afterward.
I am working on a project that uses Terminal A on machine A to output to Terminal B on Machine B, both using linux for now. I didnt see it mentioned, but perhaps you can use redirection, something like this in your webserver:
switch($_REQUEST['do'])
{ case 'test':
#process ID on the target (12345, 12346 etc)
echo system('/usr/local/bin/chbg -mt > /proc/<processID>/fd/1');
#OR
#device file on the target (pts/0,tty0, etc)
echo system('/usr/local/bin/chbg -mt > /dev/<TTY-TYPE>/<TTYNUM>');
break;
}
Definitely the permissions need to be set correctly for this to work. The command "mesg y" in a terminal may also assist...Hope that helps.
I want to read the console logs of a process that is running, I currently have this
$output = shell_exec('pgrep tfs');
echo "<pre>$output</pre>";
And that returns me a random number like 34034
I've almost never worked with linux before so I dont really know how to do this.
You do realize that that's what pgrep does, right? It returns the process ID of the process you're asking about. So that's not a random number you're getting back. Your script is working perfectly.
Why don't you find the actual log file itself (usually in /var/logs) and use something like fopen to open and parse it?
I'm currently using the following two command to generate client statements populated from mysql tables. There are three variables, client_id, date_start. date_end
wget -O mypage.html "http://mypage.php?client_id=var1&date_start=var2&date_end=var3"
wkhtmltopdf-i386 --margin-left 5mm --margin-right 5mm mypage.html mypage.pdf
This works perfectly and produces usable statements. What I would now like to do is implement a web page using three drop down menus to select each variable rather than directly typing it into linux command line. The user would select the client, date start and date end, using the web interface then click "Print Report". This would send the variables to the command line and run the two lines displayed above.
I know how to make forms but I cant figure out how to pass the variables to the command line and run these 2 lines. I'm sure its simple if anyone can help?
Many thanks
//assumes, you have extracted $clientid, $startdate, $enddate from your $_REQUEST and validated them
$command="wget -O mypage.html \"http://mypage.php?client_id=$clientid&date_start=$startdate2&date_end=$enddate\"";
exec($command, $output, $status);
if ($status!=0) die("wget failed");
$command="htmltopdf-i386 --margin-left 5mm --margin-right 5mm mypage.html mypage";
exec($command, $output, $status);
if ($status!=0) die("htmltopdf failed");
Pitfalls: You should use /path/to/wget and /path/to/htmltopdf-i386 to make sure, your PATH is OK
http://php.net/manual/en/function.system.php is the answer to your needs :)
It even gets the output for you (in case of error messages etc, very usefull)
to run multiple commands use && eg:
system("ls && exit");
I have the same issue, when I try to run it from the command line it works like a charm, but, if I try to execute it via browser it doesn't work.
I have even tested with the command line the same piece of code in a test.php file.
In command line it generates the pdf file but in browser it doesn't.
You have assigned your question as answered. I can't see where is the right answer...
Maybe you are having the same problem solved in this question exec() problem with long command in PHP
Look at Edit 3