I'm using PHP function shell_exec()to execute Shell Script.
When I use this(correct) syntax, it displays output normally
echo shell_exec("ls -l");
But, for some reason, if user enters invalid command like this
echo shell_exec("lsl -l");
by default, it should give error as it gives on terminal. But, it doesn't display anything. is there any way to catch and display errors as well; via PHP?
That's because the output of the error goes to STDERR, while shell_exec only reads STDOUT. The simplest solution would probably be to pipe STDERR to STDOUT:
<?php
echo shell_exec('lsl -l 2>&1');
If you only want to know if the command was successful, I would use exec rather than shell_exec, as you can get the return value.
From the PHP docs:
This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution failures using this function. exec() should be used when access to the program exit code is required.
If you choose to use exec() instead, you can supply a third param to the function which will return the output of the arguments:
exec ( string $command [, array &$output [, int &$return_var ]] )
If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
Related
I want to build a PHP extension that can dynamically inspect every opcode generated from a PHP file and do some checking on that.
I came across several websites and found out a couple of functions like zend_set_user_opcode_handler, but I fail to understand how this function can be used to get a complete opcode like ASSIGN !0, 50.
I'm aware of a command like php -d vld.active=1 -d vld.execute=0 -f [filename].php which I can use to generate PHP opcodes, but as far as I know you can only access the opcodes after the PHP program terminates.
What I'd like to get from the extension is an opcode which is obtained one-by-one (dynamically) as the function executes.
Can someone help me with this issue?
You could use parsekit which is available through pecl which can be downloaded from the pecl website or installed with:
sudo pecl install parsekit
Get OPcodes from a string of PHP code during runtime:
You could use the parsekit_compile_string
The syntax for this command is:
array parsekit_compile_string ( string $phpcode [, array &$errors [, int $options = PARSEKIT_QUIET ]] )
Parameters:
phpcode
A string containing phpcode. Similar to the argument to eval().
errors
A 2D hash of errors (including fatal errors) encountered during compilation. Returned by reference.
options
One of either PARSEKIT_QUIET or PARSEKIT_SIMPLE. To produce varying degrees of verbosity in the returned output.
Return Values
Returns a complex multi-layer array structure as detailed below.
An example usage of this is:
<?php
$ops = parsekit_compile_string('
echo "Foo\n";
', $errors, PARSEKIT_QUIET);
var_dump($ops);
?>
The output is too long to include in this answer but is available on the documentation page
Get OPcodes from a PHP file during runtime:
You could use the parsekit_compile_file
Very similar to the above approach but parses a file instead of a string.
I'm using shell_exec to execute a python file with a few variables and then print the real, user, and sys results to the console.
shell_exec("time /Users/$USER/anaconda/bin/python
/Applications/MAMP/cgi-bin/file.py
$var1 $var2 $var3", $result );
print_r($result);
Although this has worked for me before, it's not working now. The error I'm getting is PHP Warning: shell_exec() expects exactly 1 parameter, 2 given
It's the same response whether I just have time or /usr/bin/time.
What's going wrong here?
shell_exec() takes only a single parameter. What you were using before was likely exec().
What is in the command string that you're passing it (e.g. time or /usr/bin/time) is irrelevant to the warning you're getting.
I have written this code below which looks to see if a client is of a certain state and then exit if it is of a certain value. I have tested the query and syslog all variables being passed in to make sure they are not empty however, the return value of the exec command is 1. and $out is empty.
exec('/usr/bin/mysql --defaults-extra-file=database-user.cnf my_db -e "SELECT client_state FROM my_table WHERE transfer_id = '.$transfer_id.' AND client_id = '.$cid.'"', $out, $ret);
if($out == 15)
{
syslog(LOG_INFO, "Transfer to client ".$client->getName()." has already been completed on this transfer")
exit(EXIT_OK);
}
Beacause the output is empty it is skipping my if statement, any ideas why this command does not work and why the output is empty.
Look at the signature of the exec function:
string exec ( string $command [, array &$output [, int &$return_var ]] )
The $out variable (if your command is correct) will be an array, even if there's only 1 output line, it'll still be an array.
To know wether or not your command executed successfuly, you'll have to check your $ret variable's value. If it's anything other than zero, whatever you executed didn't run smoothly. A clean exit is marked by the program returning 0.
I can't, though, for the life of me understand why you'd bother executing a query like this. If you have mysql running, and you have php installed, why not use mysqli_* or PDO? it'll save you a lot of hasstle, and it'll improve both performance and safety of your script.
I am trying to use the PHP exec() function.
If the return_var argument is present along with the output argument,
then the return status of the executed command will be written to this
variable.
If the execution was successful, it's 0. However, if there is an error, it can be a multitude of other integers. I can't seem to find anywhere what those integers correspond to. How should I interpret the integer that I get?
Update:
I really should have specified this originally, but I am executing another PHP script. Unlike rsync, which has exit values on its man page, I can't find an equivalent for PHP.
So what I am doing is something like:
$rv = exec('php file.php', $out, $rv);
The return value is dependent on the process/program that you ran with exec. For instance, if you ran grep:
The exit status is 0 if selected lines are found, and 1 if not
found. If an error occurred the exit status is 2. (Note: POSIX
error handling code should check for '2' or greater.)
rsync has about 20 different error exit codes, all painstakingly explained in the man page:
http://linux.die.net/man/1/rsync
so yes, it's program-dependant :)
Even if you're running PHP script, the exit value depends on your program itself. By default php scripts will exit with 0. If you use the exit function you can return different exit codes:
http://php.net/manual/en/function.exit.php
If you want to experimentally determine what your php program exits, call it on the command line:
php file.php
then do
echo $?
this will show you the exit value of your php script.
IMHO, before use exec() function better set output and return_var parameters and read return code execution by return_var.
Don't rely on exec() return value.
Look up the manual page for the command that you are executing. This value has nothing to do with PHP but the actual command.
I have a php script that handles a form input. For design reasons both a bit out of my control, and which I do not entirely wish to change, I have to call a perl script with the parameters specified in the html form.
I sanitized all inputs and then output them to a file called input, which is read by the perl script named, for sake of brevity in this question, script.pl. Script.pl should do some stuff and then write all outputs to a file named output.
I call the perl script from php like so:
system('perl script.pl 2>errors');
No good, nothing happens. output is not created, errors is not created, and the side effect does not occur.
My apache runs as www-data user and group id. My directory is set with 775 settings with ownership as me:www-data. (My user name is replaced with "me" for sakes for privacy).
My question is two fold:
1) Am I doing this wrong? If so how should I improve upon the code?
2) Is there a more sane way to catch errors in system execution?
After programming in perl for a while, php feels like a pain in the ass.
OS: Ubuntu server edition
popen can be used to get the shell's response. that is your best bet. Which can help you debug why system is angry. also, if your pl is saying "hello" and "bye", popen can even read that.
If the command to be executed could not be found, a valid resource is returned. This may seem odd, but makes sense; it allows you to access any error message returned by the shell
Ideally, I would have taken data from stdin and written to stdout. popen would allow neat access to both.
popen('pwd;perl script.pl 2>errors;echo done');
then you can see where were you (directory) when system got called and did it "done".
In the past I have used shell_exec() or backticks to accomplish this.
The documentation for shell_exec's return value indicates it is identical to the backtick operator:
Return Values
The output from the executed command.
Hope that helps.
system() only returns the status code.
$var = shell_exec ("ls");
print $var;
$var = `ls -l`;
print $var;
Is perl in the path? Maybe you need to specify it fully (e.g. /usr/bin/perl). Is system() returning false, indicating a failure? If you try something simpler, like system('/usr/bin/true', $retval), does $retval get set to 1?
Take a look at the PHP system() documentation. The following is the function prototype of system():
string system ( string $command [, int &$return_var ] )
Pass in a 2nd argument and then print out the return string as well as the second variable. See what the error says.