Suppose I have the following PHP script being run on the PHP CLI in a shell script:
<?php
# foo.php
$a = rand(1,5);
if ($a == 1) {
fwrite(STDOUT, 'normal condition');
} else {
fwrite(STDERR, 'error condition');
}
The script is run in the shell like so:
php foo.php
How do I handle the output from the PHP script in the shell based on whether the output is to STDERR or STDOUT? For instance, if the output from the PHP script is STDOUT, write it to a CSV file, but if the output is to STDERR, write the output to an error log file.
2
Answers
You redirect each stream to separate locations.
php file.php > outfile.csv 2> errorlog.txt
See https://askubuntu.com/questions/625224/how-to-redirect-stderr-to-a-file for more details
Some possibilities that produce a single output file.
Option 1 – redirect
stdout
andstderr
to separate files, then remove empty files:The
! -s
test will be true if a file is zero-length. This version uses some fairly common shell idioms, and should work in bothzsh
andbash
. The operations can be combined into a function:Option 2 – save
stdout
andstderr
in shell variables, and only create the files if there is output:Some of the pieces:
>
,2>
– redirectstdout
andstderr
.>(...)
– process substitution. The shell creates a subprocess (sort of – see below) and sends the output that we’ve redirected to that process.t=$(<&0)
– store thestdin
of the subprocess in the variablet
.[[ -n ... ]]
– test if the string is non-empty.<<<... > ...
– use a here-string to write the variable contents to a file.This version comes with some caveats:
zsh
(or more accurately, it did not work in my very brief tests withbash
).zsh
built-ins, so the shell runs them synchronously within a single process. Other variations of this pattern might behave differently – the zsh documentation describes a workaround if that is an issue.This can also be written as a function:
Alternative solutions:
php
command succeeded by testing the shell return code instead of looking at the output files.php
code is a possibility, that script could write directly to the data and error files instead of passing the information through the shell.