46

I have been trying to let know know if the exec() command in php executes successfully or not so i can echo certain messages accordingly. I tried the following piece of code but the problem with it is that whether exec() runs successfully or not it always echo "PDF not created" and never echo pdf created successfully. Kindly let me know how can i perform the check on the execution of exec() so i can echo messages accordingly Thanks,

<?php
if (exec('C://abc//wkhtmltopdf home.html sample.pdf'))
echo "PDF Created Successfully";
else
echo "PDF not created";
?>
soft genic
  • 2,016
  • 3
  • 27
  • 44

5 Answers5

72

According to PHP's exec quickref, you can pass pointers in to get the output and status of the command.

<?php
exec('C://abc//wkhtmltopdf home.html sample.pdf', $output, $return);

// Return will return non-zero upon an error
if (!$return) {
    echo "PDF Created Successfully";
} else {
    echo "PDF not created";
}
?>

If you want to enumerate the possible errors, you can find the codes over at hiteksoftware

Matt Williamson
  • 39,165
  • 10
  • 64
  • 72
  • what about long scripts? how do i modify the code to make it work for running long python scripts inside exec? – proprius Feb 03 '16 at 15:08
  • 2
    $return can also be null if the exec failed to finish, e.g. ran out of disk space during the command. Thus this is not fool proof solution, see my answer for a better one. – malhal Mar 24 '16 at 21:04
  • i have created a home.html file and written your code in index.php file then run in browser, it does not work for me. – Kamlesh Oct 04 '19 at 04:00
15

The correct way is to check that the $return_var was not set to zero because it is only set to zero when it is successful. In certain cases the exec can fail and the return_var is not set to anything. E.g. if the server ran out of disk space during the exec.

<?php
exec('C://abc//wkhtmltopdf home.html sample.pdf', $output, $return_var);
if($return_var !== 0){ // exec is successful only if the $return_var was set to 0. !== means equal and identical, that is it is an integer and it also is zero.
    echo "PDF not created";
}
else{
    echo "PDF Created Successfully";
}

?>

Note : do not initialize $return_var to zero

malhal
  • 26,330
  • 7
  • 115
  • 133
  • 1
    Where is it mentioned that $return_var should be set to 0 if successful? – Sandeepan Nath Apr 05 '16 at 12:55
  • 1
    "the return status of the executed command will be written to this variable" http://php.net/manual/en/function.exec.php So if there is no return status because the command just didn't even finish then it won't be set to anything. This is the reason it is better to check for it being set to 0 rather than other way around. – malhal Apr 05 '16 at 12:58
  • 1
    Oh I see what you mean,"common programming practice for a child process to return zero to the parent signifying success": https://en.wikipedia.org/wiki/Exit_status – malhal Apr 05 '16 at 12:59
  • Ok, so it is not something limited to exec, but rather based on how processes work. – Sandeepan Nath Apr 05 '16 at 13:26
  • 1
    Well processes can return whatever they like, but the convention is to use zero to mean success, so most of the time it will be that, and definitely if you are using any standard tools. – malhal Apr 05 '16 at 13:29
  • 1
    what $output that contains? – Pooja Khatri Mar 07 '18 at 07:01
  • 1
    how can i only get the return value without loading stuff into $output? – Thomas Fellinger Apr 19 '20 at 09:04
5

A simple sample:

$ip = "192.168.0.2";
$exec = exec( "ping -c 3 -s 64 -t 64 ".$ip, $output, $return );
echo $exec;
echo "<br />----------------<br />";
print_r( $output );
echo "<br />----------------<br />";
print_r( $return );

In case of not ping or ERROR. ( ONE )

----------------
Array ( [0] => PING 192.168.0.2 (192.168.0.2) 64(92) bytes of data. [1] => [2] => --- 192.168.0.2 ping statistics --- [3] => 3 packets transmitted, 0 received, 100% packet loss, time 2016ms [4] => )
----------------
1

In case of success ( ZERO )

rtt min/avg/max/mdev = 4.727/18.262/35.896/13.050 ms
----------------
Array ( [0] => PING 192.168.0.2 (192.168.0.2) 64(92) bytes of data. [1] => 72 bytes from 192.168.0.2: icmp_req=1 ttl=63 time=14.1 ms [2] => 72 bytes from 192.168.0.2: icmp_req=2 ttl=63 time=35.8 ms [3] => 72 bytes from 192.168.0.2: icmp_req=3 ttl=63 time=4.72 ms [4] => [5] => --- 192.168.0.2 ping statistics --- [6] => 3 packets transmitted, 3 received, 0% packet loss, time 2003ms [7] => rtt min/avg/max/mdev = 4.727/18.262/35.896/13.050 ms )
----------------
0
devasia2112
  • 5,844
  • 6
  • 36
  • 56
0

i do work for me

for system linux and lang:php,laravel

exec('/usr/bin/tesseract 2.png out1 -l '.$lang,$output,$error);
           return (!$error)? "success":"Error";
Netwons
  • 1,170
  • 11
  • 14
0

I would suggest to use the next method if you don't care about return code:

private function execCommand($command) {
    exec($command, $output, $return);

    return $return === 0;
}

then simply call it like:

if ($this->execCommand("C://abc//wkhtmltopdf home.html sample.pdf")) {
    echo "Success";
} else {
    echo "Error";
}
Manolo
  • 24,020
  • 20
  • 85
  • 130