So I have a php script which I execute using the following command:
php -f my_script.php myArguments
The script is under version control using svn. I just updated it, pasted the command to run it into a terminal, and executed it. However, there is no output. Not a failure message, not it printing anything, nothing. It looks like it never starts. Kind of like the following:
me:/srv/scripts# php -f my_script.php myArguments
me:/srv/scripts#
Other scripts will run just fine.
It is difficult for me to come up with an SSCCE, as I can't really share the code that is causing this, and I haven't been able to replicate this behavior intentionally. I have, however, seen this twice now. If I save my changes, revert the file, and paste them back in, there is a strong chance it will run just fine.
However, I am concerned by not knowing what is causing this odd behavior. Is there a whitespace character or something that tells PHP not to start, or output anything?
Here is what I've tried after seeing this behavior:
Modifying the script so it is a simple echo 'hello'
Putting nonsense at the beginning of the script, so it is unparseable.
Pasting in code from a working script
Banging my head on a wall in frustration
Trying it in another terminal/putty ssh connection.
Here's where it gets interesting: It actually works in a different terminal. It does everything as expected.
So does anyone have any ideas what might be causing this, or things I should try in order to determine the problem?
EDIT:
The "different terminal" is still the terminal application, just a new one.
I have sufficient permissions to execute the file, but even if I didn't, it should spit out a message saying I don't.
I intentionally introduced syntax errors in hopes that I would get PHP to spit out a parse error. There was still no output.
display_errors might be disabled before runtime. You can turn it on manually with the -d switch:
php -d display_errors=1 -f my_script.php myArguments
I came across the same issue, and no amount of coercing PHP to display_errors or checking for syntax with -l helped
I finally solved our problem, and perhaps you can find some help with this solution
Test your script without using your php.ini:
php -n test_script.php
This will help you hone in on the real cause - PHP configuration, someone else's script, or your script
In my case, it was a problem with someone else's script which was being added via the auto_prepend_file directive in the php.ini. (Or more specifically, several files and functions later as I drilled through all the code adding debug as I went - on a side note, you may find that using fwrite(STDOUT, "debug text\n"); invaluable when trying to debug this type of issue)
Someone had added a function that was getting run through the prepend file, but had used the # symbol to suppress errors on a particular function call. (You might have a similar problem but not specifically related to the php.ini if you have any includes in your test script bringing in other code)
The function was failing and caused the silent death of PHP, nothing to do with my test script
You will find all sorts of warnings about how using the # symbol causes the exact problem I had, and perhaps you're having, http://php.net/manual/en/language.operators.errorcontrol.php.
Reproduction of similar symptoms:
Take a fully functional PHP environment, and break your CLI output by adding this the top of your script
#xxx_not_a_real_function_name_xxx();
So you may just have a problem with the php.ini, or you (or someone else) may have used # not realising the serious (and frustrating and time consuming) consequences that it causes in debugging
I experienced PHP CLI failing silently on a good script because of a memory limit issue. Try with:
php -d memory_limit=512M script.php
Related
Let me start by saying I am totally not a PHP programmer - this was dumped on me to fix.
I have a function that sits in a file by itself, that basically looks like this:
<?php
function UploadFile($source, $destination){
$debugLogPath = '/biglongpath/debug.log';
file_put_contents($debugLogPath,PHP_EOL . "Beginning UploadFile function", FILE_APPEND);
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
require_once('Net/SFTP.php');
...Rest of the ftp code here...
}
?>
It's using phpseclib. If I run the main PHP script (that calls this function...) via a web browser, everything works great. When I run that same script via a CRON job, it dies as soon as this function is called. I've verified this by writing out a debug log right before calling the function - the first statement before the function is written to the log, but the "Beginning UploadFile function" is never written.
I'm guessing that maybe it has something to do with the require_once statement - maybe either a path problem or permissions issue when it's executed via CRON?
I've tried wrapping the entire function contents in a try/catch and writing out the Exception, but it still just dies.
I wonder why there are 3 helpful flags, when the question states, that the file is being written? However, this is not the CLI error log and therefore will not automagically log any errors there.The second one suggestion made appears more likely, while there are even more possibilities:
Make sure that these modules are being loaded for the PHP-CLI:
libsodium, openssl, mcrypt, gmp (as the composer.json hints for).
Running php --ini should show which INI files were loaded. Even if the corresponding INI files are there, make sure the instructions inside them are not commented out with a ;.
Manually running the script from CLI, as the user which runs the cronjob suggested, with error reporting enabled. If this shouldn't help, single-step into it with xdebug, to see where exactly it bugs out (NetBeans, Eclipse, VS Code and a few other IDE do support PHP debugging). This requires some effort to set it up, but then it provides a far better debugging methodology.
I have a backup script that runs from the browser without a problem. It extracts data from the database and writes it to a ZIP file that's under 2MB .
It mostly runs from the server, but it fails (silently) when it hits a particular line:
require ('/absolute-path/filename'); // pseudo filespec
This is one of several such statements. These are library files that do nothing but 'put stuff in memory'. I have definitely eliminated any possibility that the path is the problem. I'm testing the file with a conditional is_readable(), output it, and sent myself emails.
$fs = '/absolute-path/filename'; // pseudo filespec
if (is_readable ($fs) ) {
mail('myaddress','cron','before require'); // this works reliably
require ($fs); // can be an empty file ie. <?php ?>
mail('myaddress','cron','after require'); // this never works.
}
When I comment out the require($fs), the script continues (mostly, see below).
I've checked the line endings (invisible chars). Not on every single include-ed file, but certainly the one that is running has newline (NL) endings (Linux-style), as opposed to newline + carriage return (NL CR) (Windows style).
I have tried requiring an empty file (just <?php ?>) to see if the script would get past that point. It doesn't.
I have tried calling mail(); from the included script. I get the mail. So again, I know the path is right. It is getting executed, but it never returns and I get no errors, at least not in the PHP log. The CRON job dies...
This is a new server. I just migrated the application from PHP 5.3.10 to PHP7. Everything else works.
I don't think I am running out of memory. I haven't even gotten the data out of the database at this point in the script, but it seems like some sort of cumulative error because, when I comment out the offending line, the error moves on to another equally puzzling silent failure further down the code.
Are there any other useful tests, logs, or environment conditions I should be looking at? Anything I could be asking the web host?
This usually means that there is some fatal error being triggered in the included file. If you don't have all errors turned on, PHP may fail silently when including files with certain fatal errors.
PHP 7 throws fatal errors on certain things that PHP 5.3 did not, such as Division by Zero.
If you have no access to server config to turn all errors on, then calling an undefined function will fail silently. You can try debugging by putting
die('test');
__halt_compiler();
at the beginning of a line, starting from the top, on the line after the first <?php tag and see if it loads. If it does slowly displace line by line (though don't cut a control structure!) and retest after each time and when it dies you know the error is on the line above.
I believe the problem may be a PHP 7 bug. The code only broke when it was called by CRON and the 'fix' was to remove the closing PHP tag ?>. Though it is hard to believe this could be an issue, I did a lot of unit testing, removing prior code, etc. I am running PHP 7.0.33. None of the other dozen or so (backup) scripts broke while run by CRON.
As nzn indicated this is most likely caused by an error triggered from the included file. From the outside it is hard to diagnose. A likely case is a relative include/require within that file. A way to verify that is by running the script on console from a different location. A f might be to either call cd from cron before starting PHP or doing a chdir(__DIR__) within the primary file before doing further includes.
I've got some PHP code that I want to run as a background process. That code checks a database to see if it should do anything, and either does it or sleeps for awhile before checking again. When it does something, it prints some stuff to stdout, so, when I run the code from the command line, I typically redirect the output of the PHP process to a file in the obvious way: php code.php > code.log &.
The code itself works fine when it's run from the shell; I'm now trying to get it to run when launched from a web process -- I have a page that determines if the PHP process is running, and lets me start or stop it, depending. I can get the process started through something like:
$the_command = "/bin/php code.php > /tmp/code.out &";
$the_result = exec($the_command, $output, $retval);
but (and here's the problem!) the output file-- /tmp/code.out -- isn't getting created. I've tried all the variants of exec, shell_exec, and system, and none of them will create the file. (For now, I'm putting the file into /tmp to avoid ownership/permission problems, btw.) Am I missing something? Will redirection just not work in this case?
Seems like permission issues. One way to resolve this would be to:
rename your echo($data) statements to a function like fecho($data)
create a function fecho() like so
.
function fecho($data)
{
$fp = fopen('/tmp/code.out', 'a+');
fwrite($fp, $data);
fclose($fp);
}
Blurgh. After a day's hacking, this issue is finally resolved:
The scheme I originally proposed (exec of a statement with
redirection) works fine...
...EXCEPT it refuses to work in /tmp. I
created another directory outside of the server's webspace and opened
it up to apache, and everything works.
Why this is, I have no idea. But a few notes for future visitors:
I'm running a quite vanilla Fedora 17, Apache 2.2.23, and PHP 5.4.13.
There's nothing unusual about my /tmp configuration, as far as I know (translation: I've never modified whatever got set up with the basic OS installation).
My /tmp has a large number of directories of the form /tmp/systemd-private-Pf0qG9/, where the latter part is a different set of random characters. I found a few obsolete versions of my log files in a couple of those directories. I presume that this is some sort of Fedora-ism file system juju that I will confess to not understanding, and that these are orphaned files left over from some of my process hacking/killing.
exec(), shell_exec(), system(), and passthru() all seemed to work, once I got over the hump.
Bottom line: What should have worked does in fact work, as long as you do it in the right place. I will now excuse myself to take care of a large bottle of wine that has my name on it, and think about how my day might otherwise have been spent...
I have a question regarding running a shell command via PHP. My goal is to successfully run compass compile [project] via PHP. I have tried the following:
echo system('compass compile [project]', $s); // prints [31m[0m
echo $s; // prints 1
echo passthru('compass compile [project]', $p); // prints [31m[0m
echo $p; // prints 1
echo shell_exec('compass compile [project]'); // prints [31m[0m
echo exec('compass compile [project]', $e, $ee);
print_r($e); // Array ( [0] => [31m[0m )
echo $ee; // prints 1
I even tried running a shell command to an executable file that contained compass compile test and I still got the same results as the trials above.
My questions
What does [31m[0m mean? Does this represent binary data? Do these represent bash colors as search engines suggest?
As far as I know, the output should be the following:
For kicks, I tried to execute via system(/usr/local/bin/compass compile [project]); and I got the same result. I double checked my path so I know I can execute these commands as expected. Here is the output from echo $PATH:
/usr/lib/lightdm/lightdm:
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:/bin:
/usr/games:
/usr/local/games:
/var/lib/gems/1.9.1/bin
Is there a way to compile compass projects using PHP?
I've seen a similar error before.
Typically it is due to the things being output in the bash startup scripts. For example, I had an echo in one of my bash startups that jacked up a lot of scripts till I realized what was causing the problem.
Or, perhaps the user (www-data ?) doesn't actually have a home dir and appropriate startup scripts in place?
You can try this to get a non interactive shell:
exec("/bin/bash -c \"compass compile [project]\"", $e, $ee);
print_r($e);
echo $ee;
If you still have issues, try redirecting the output to a tmp file, an checking it:
exec("/bin/bash -c \"compass compile [project] > /tmp/compass.compile.output\"", $e, $ee);
print_r($e);
echo $ee;
See also: What's the difference between .bashrc, .bash_profile, and .environment?
The issue was fixed by using sass --compass and redirecting the stderr to stdout via echo shell_exec("sass --compass [project] 2>&1");
It was a pretty long and arduous process figuring this out since it's been awhile since I've dabbled in command line programs. Remember that error streams and output streams might be on different outputs. The easiest way to test this is to shovel the output into a file via:
# do this once with a good file and once with a file that will give errors
sass --poll style.scss > output.txt
If output.txt is empty then the error output is on the stderr stream such as the case above. We can correct this by redirecting the stderr to the srdout. For example:
sass --poll > output.txt 2>&1
#shows results
cat output.txt
I created a simple PHP script that redirects the output from one textarea to the other. The code can be found here.
First guess would be a permissions issue. Odds are the user account running PHP (unless you're running this from the command line, I'm guessing that this is the user that the httpd apache daemon is running under) doesn't have the permissions to do what you're asking. The errors are extremely unhelpful, however.
From what I can tell, it looks like an attempt to have the error show up in red on the command line. My guess is that there are hidden (or somehow never printed out) characters in-between the codes. Check out some of your apache and/or PHP error logs to see if anything helpful is showing up there that never made it into the PHP variable. Or, for kicks, try copy and pasting the output with the bash colors into a basic text editor and first delete each character from the beginning one by one... see if anything magically appears. If that doesn't work, try the same in reverse, backspacing from the end. Either way, there's an error occurring, so important that it must show in bold red letters to you, it's just not getting to you.
If it does in fact turn out to be a permissions issue, and it's one you can't remedy through permissions wrangling, you could create an intermediary file that your Apache user has permissions to write to, and your cron user has permissions to read from. Instead of running the code directly from PHP, put it in the file, then run a cron on a frequent basis looking for anything in that file, CHECKING IT FOR VALIDITY, and then running it through the compiler and removing it from the file.
It'd be ugly, but sometimes pretty things don't work.
You guessed it right it is colors but the way it is defined is not right. For more information regarding using colors in console please refer to this document. Also, for compiling SCSS via compass you can use shell_exec command in linux. For more information regarding shell_exec please refer to this document. Let us know how it goes.
I have a php script running on OSX snow leopard. When I run it from the command line it throws
'Segmentation Fault'
. If I put an exit() at the end of the file, it doesn't throw the error. Why is the exit needed?
I've had segfaults like this when extensions don't play nicely together. In one case it was curl and pgsql, and swapping the order they were loaded made the problem go away. (Swap the extension.so lines in php.ini, or rename files (z-curl.ini, for example) if you have a conf.d setup.)
Without seeing code it's tough to answer. Try a divide and concur method of debugging: Disable all the code with a comment. See if the problem occurs. If not, enable the first half of the code. If the problem reappears, disable all but the first quarter of the code. Continue to divide and concur until you find the part of the script that's causing the problem.
My guess would be you're not closing some open handle. But again I'm just guessing as I can't see the code.