OK -- I'm a PHP newbie and stumped by exec() error handling.

The short version is that I try to run:

exec("cp testA.dat testB.dat") or die ("Bad cp.");

and what I get is both the copied file from exec AND the die message (and halted PHP).


I'm running PHP 5.2.6 under XAMPP 1.6.7 for Linux (on Fedora 9). Safe mode is off (I checked my php.ini.) PHP is running as user "nobody." When I try the command:

exec("cp testA.dat testB.dat") or die ("Bad cp.");

or, alternatively,

(exec("cp testA.dat testB.dat")) or (die ("Bad cp."));

I always get the "Bad cp." message (and the PHP is halted, as per the die command) -- but the file testA.dat is successfully copied to testB.dat.

I get exactly the same result if I use absolute paths (for the command and for the original file and for the destination.)

If I just run the exec command, without including "or die," the command runs.

If I instead use the command

exec("cp testA.dat testB.dat", $output_array, $return_val);

the command runs and I get a blank $output_array (since there's no output to terminal) and a $return_val of 0.

If I try setting the result in a variable instead of using die:

$success = exec("cp testA.dat testB.dat");

then $success always comes up false (but testA.dat is still copied to testB.dat.).

If I use system() or passthru() instead of exec(), again I get the same result -- die() still dies, or $success comes up false, whether or not I use absolute paths. (But the file is still copied successfully.)

For reference, user "nobody" is what Apache/PHP are running as, the owner of the base directory for the web server (where testA.dat is sitting) is "nobody" and the owner has rwx permissions for the directory, and both the owner and group of testA.dat is "nobody"; the file permissions for testA.dat are -rwxr-xr-x.

Why in the world am I apparently getting exec(cp) AND die?!

Though getting rid of the error checking ( or die() ) allows the command to work, I'd be much happier being able to actually error-check my commands instead of blithely assuming they run when I call them from PHP. And while cp is a trivial command, it is important for me to be able to call a much more complicated external program which will take an input file and from it, produce an output file.

I'm pretty flabbergasted here, and appreciate any help you can offer!

    The PHP exec() function does not return a boolean true/false, rather it returns the last line of output from the invoked command. As a successful cp probably returns no output, that empty string would be evaluated as false, thus executing your die() after the "or" operator. Trapping the result of the cp command via the optional 3rd param to exec() is probably on the right track, noting that the CP man page says it returns 0 on success, > 0 on any other result. So you could execute the exec() with that 3rd arg, then check if it is non-zero for an error condition.

    exec("blah blah blah", $output, $result);
    if($result > 0)
    {
       die('error message here');
    }
    

    PS: Of course, you could just use PHP's [man]copy/man function, instead, which in addition to being simpler, it returns boolean true/false on success/failure and is platform-independent.

      Write a Reply...