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.
Related
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'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.
I could not find the reason why my request fail for the following
My php code is:
if (isset($_COOKIE["user"])) {
echo '<p><h3><strong>Welcome '.$_COOKIE["param"].'</strong></h3></p>'; .....
When i request exec('ls -al') as param , the php code did not run the command.
On the response of the request it was like parameterized:
Welcome exec('ls -al')
What may the reason that failed this execution?
$_COOKIE["param"] is a string. You are echoing it. It is not supposed to run anything.
If you wanted to run a command in your PHP, you would have to use eval(). But as for running a command from a cookie value:
DON'T DO IT!
So you're saying that the value of $_COOKIE['param'] is exec('ls -al'), and you're expecting that to run when you echo it out?
That's not how it works. The value of that cookie will be the string value "exec('ls -al')", not the result of the executed code. If you think about it for a second, you'll understand why it would be a bad idea for a cookie to be able to auto-execute code.
It's not really a great idea to be running random commands through exec() anyway, especially if that input came from a user (which cookies do - the user can and will change them to try to attack you).
Instead, you should be using other input that your code can interpret as a signal to run certain code. For example, you could have the param value hold the string list files, and your code would see that value and run exec('ls -al') for you.
You still shouldn't be execing code to do this though, since it's very easy to accidentally run dangerous commands that way. Instead, you should use PHP's built-in functions as much as possible, and only after sanitizing your inputs and only running known values.
For your case, PHP has a bunch of functions that let you interact with the filesystem of your server. Use those to get a list of files on the system instead.
I believe that all of these (and even die() or die(0)) are identical. If they are not identical, which is preferred for exiting a script successfully? If they are identical, is there any preferred standard to indicate successful script completion? I tend to use exit;.
EDIT: All of the answers have "die() and exit() are identical" even though I say that in my question. I updated to the title to hopefully make it clearer that this is NOT my question. I want to clearly indicate success from a command line script.
These are all identical. I'm pretty sure die() is just a straight-up alias to exit(), but even if it isn't, it still acts identically.
When one of these functions is given a string argument, it prints out the string before terminating the process. When it encounters an integer under 255, that integer is considered the return code for the process, which gets passed back to the process which invoked the PHP script. This is particularly useful when writing command line applications (PHP isn't web-only!).
As far as the difference between exit, exit(), and exit(0), there really is none. There is definitely no difference between the first two because exit is technically a language construct, not a function, so it can be called with or without parentheses, just like echo. Returning a code of 0 means "this program ran successfully/without errors", and while I don't know what exactly happens when you don't pass an argument, PHP.net says that an argument-less exit indicates success, so I would bet it returns 0, though again PHP.net doesn't show a default for the argument.
As several people have mentioned, die() and exit() are exactly the same.
If you look at the PHP documentation, there are two options for arguments:
An numeric value. This is only useful if you are using PHP from the command line, as opposed to a web server. A value of zero indicates success. Nonzero indicates a failure condition occurred.
A string value. This will be displayed to the browser when the exit occurs.
Instead of die() or exit(), I recommend using exceptions and a custom top-level exception handler to manage failure conditions.
You have more flexibility that way to do things like automatic error logging. Also, if you're using PHP to implement a JSON API, this exception handler can hand back a valid, error-indicating JSON snippet instead.
I would say that in regards with a better semantics die($arg); should be used for an abnormal or unexpected termination, even when -of course- you still have caught it. And exit($arg); should be used for a normal (expected / controlled) end of a process, like in break; for a for or while or a switch structure but with a definitive end.
Nevertheless .. I personally often use a general if { } else { } structure to control different branches of huge processes or output buffering so not having to use "exit" ..
I also use die($arg) in simple error-catching semantics like in
$db = mysql_connect([$args]) or die ($error); ...
die(); is just a synonym for exit(); and is functionally identical.
The standard way is to use exit code zero to signify success, and anything else to denote an error condition.
die() is typically used to kill the script with an error output:
die("There was a fatal error");
where-as exit is typically used as a successful exit (At least in my coding)
The PHP Manual says that the functions are identical.
I will get downvoted to hell, but in some cases when hacking in CLI, we do not want the program to get killed, while not wanting to continue the full execution.
Here the goal is to avoid making api calls to a separate hand-point file. Say I have a nice play button in my interface, that execute system calls.
Example 1: The program get killed after the job , no datas returned. This is not wanted.
if ($_GET["play"] != ""){
// Some job
exit;
}
/* Huge amount of data*/
Example 2: The program still runs, feeding the whole data in the GET request. This is unnecessary on this case. This is slowing down the browser with all the data, that he has already.
if ($_GET["play"] != ""){
// Some job
}
/* Huge amount of data*/
Example 3: The program still runs, no data returned as expected, the play command had been executed, but the whole data set get parsed, this is unnecessary job, can slow down php/the machine.
/* Huge amount of data*/
if ($_GET["play"] != ""){
// Some job
}
Example 4: The program still runs, no data returned as expected, the play command had been executed, the whole data had not been parsed, php returned super quickly 200OK with an empty response, as expected. Everyone happy!
if ($_GET["play"] != ""){
// Some job
goto END;
}
/* Huge amount of data*/
END;
Yes! Using GOTO, sometimes is to be considered -as the best to do 🔨 -!
https://www.php.net/manual/en/control-structures.goto.php
die is exactly equivalent to exit.
From the manual:
If status is an integer, that value will be used as the exit status..
This is only useful if you have some sort of wrapper that does something based on the exit status. Unless you have a specific need to report an exit code to the outside world, just exit;.
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.