PHP system() - return status is always 0
I need to get the following scripts running.
// File: script_a.php
<?php exit(1); ?>
// File: script_b.php开发者_Go百科
<?php
system('php script_a.php', $return);
var_dump($return);
?>
Now my problem: On my windows system running script_b.php
shows int(1)
as expected. On our Unix-Server I always get int(0)
, what makes it impossible for me to check, if a certain failure happens inside the script_a.php
.
Does anybody knows this problem and how to solve it?
You might want to check if it's calling the right php executable on th Unix machine. On many UNIX systems you would need to call the php-cli executable insted of the php one for use on the command line. Another thing to check would be permissions. Maybe the user executing the script_b.php script doesn't have permissions to execute script_a?
__halt_compiler()
is called somewhere , able to check that ?
Try making the PHP system
call with the absolute path of both the PHP executable and the script filename, e.g.: system('/usr/bin/php /path/to/script_a.php', $return);
. Maybe it's a path issue. (You may find the absolute path of your PHP executable with: which php
).
Also, as someone suggested, try debugging the actual return value of script_a.php on your UNIX server by running php script_a.php; echo $?
on the command line. That echo
will output the last return value, i.e., the value returned by script_a.php.
Anyway, I suggest doing an include
with a return
statement as described in Example #5 of the include() documentation. If you can adapt your scripts like this, it's a more efficient way of communicating them.
// File: script_a.php
<?php return 1; ?>
// File: script_b.php
<?php
$return = (include 'script_a.php');
var_dump($return);
?>
Have you checked if safe_mode is enabled on unix server?
PHP Note:
Note: When safe mode is enabled, you can only execute files within the safe_mode_exec_dir. For practical reasons, it is currently not allowed to have .. components in the path to the executable.
Or maybe the system function is forbidden to be executed?
I can't reproduce it either (PHP 5.3.3, Ubuntu).
When I set the exit-value to something better grep-able, like "666", tracing the scripts returned also what is expected:
strace -f php5 script_b.php 2>&1 | grep EXITSTATUS
[pid 18574] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0, NULL) = 18575
waitpid(18574, [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0) = 18574
The "-f" to strace let's it follow child processes as you use the system call. "2>&1" redirects stderr to stdout to let everything grep. You can also pipe it to "|less" to go through but the output is long and not very readable.
I can't reproduce this on my system, Ubuntu Hardy. Here's a sample:
/tmp$ mkdir /tmp/sbuzz
/tmp$ cd /tmp/sbuzz
/tmp/sbuzz$ echo '<?php exit(1); ?>' >script_a.php
/tmp/sbuzz$ cat >script_b.php
<?php
system('php script_a.php', $return);
var_dump($return);
?>
/tmp/sbuzz$ php script_b.php
int(1)
/tmp/sbuzz$ echo '<?php exit(2); ?>' >script_a.php
/tmp/sbuzz$ php script_b.php
int(2)
/tmp/sbuzz$
Exit code 0 means successful execution of the program, so it kind of sounds like you are perhaps running the wrong script_a.php or perhaps the "php" executable isn't doing what you are expecting? Perhaps you have a script called "php" that is in your path before the interpreter? What does "which php" report? On my system it says "/usr/bin/php".
If PHP can't find the script, it would exit with 1, for example:
/tmp/sbuzz$ cat script_b.php
<?php
system('php doesnt_exist_script_a.php', $return);
var_dump($return);
?>
/tmp/sbuzz$ php script_b.php
Could not open input file: doesnt_exist_script_a.php
int(1)
/tmp/sbuzz$
In this case I changed the script_b.php to try to run a script that doesn't exist, and I get the exit code 1 (it should be 2 if it completed successfully, because I changed the script_a above), but it also shows the error that it couldn't run the program.
You might want to try changing it to specifically run the full path to the PHP executable:
system('/usr/bin/php script_a.php')
or also the full path to the script as well:
system('/usr/bin/php /tmp/sbuzz/script_a.php')
You could also try specifically executing a program that will return 1, just as another data-point, such as:
system('false')
system('bash -c "exit 69"')
You might want to try an exit code other than 1, which is a common failure. That's why I did "exit 69" above. "false" will exit with 1.
Also, of course, try running the script_a.php directly:
/tmp/sbuzz$ php script_a.php
/tmp/sbuzz$ echo $?
2
/tmp/sbuzz$
The "$?" is the exit code of the last run command, at the shell prompt.
Try:
<?php
die(1);
?>
If that fails as well, check out the stdout of:
strace php script_a.php
Not sure if these problems are related, but you may take a look on exec always returns -1 (or 127) as i had a similar problem in the past... even if i didn't acually solved it.
In your case, it might be another problem, not sure how it would be reproduceable, but i've seen caeses where the return string for an unknown command would be the return string from bash
(bash: command not found
). On most servers i dont anything though. You may try and check the shell setup for the current user(i assume it would be www-data)
Taking in consideration of your comment that your problem is occuring in UNIX system when your script_b is something like
system('php script_a.php | tee myLogFile', $return);
You may use this syntax
system("bash -c 'php script_a.php | tee log.txt ; exit \${PIPESTATUS[0]}'", $return);
Do man bash and search for PIPESTATUS for more details.
I know this is an old thread, but I just had a similar problem.
The exit status was being set to 0 when I had the script run in the background, something like
system('php script_a.php &', $return);
Could you have been doing that but just generalizing for readability?
you need to be running as root or use sudo to access via php.
try something like this:-
system('sudo /usr/bin/php -f script_a.php', $return);
in your script_b.php
and edit /etc/sudoers to add the following line:-
apache ALL=(ALL) NOPASSWD: /usr/bin/php -f script_a.php
if php is not in /usr/bin/php change that reference and also mention the full path of script_a.php file somthing like /var/www/html/script_a.php or path where it is physically located.
Thanks.
精彩评论