bash – Why Does This IF Statement Work on Command Line but Not in Script?

bashshell-script

The following works on the command line as root

if [[ -e /var/log/apache2/error.log ]]; then echo YES; fi
YES

yet this, in a script, does not

if [[ -e /var/log/apache2/error.log ]]; then
    echo YES
fi

Any idea why this might be? I'm not getting the expected output or an error.

First line of the script is #!/bin/bash

As the script is called by a PHP script (www-admin), I thought maybe its due to file permissions, but the error.log file has read permissions

-rw-r--r-- 1 root adm 1763810 Sep 17 09:02 /var/log/apache2/error.log

Parent folder permissions

drwxr-xr-x  10 root root  4096 Mar 20  2019 var
drwxr-xr-x 5 root root 12288 Sep 17 06:25 log
drwxr-xr-x 2 root root       4096 Sep 17 06:25 apache2

How the PHP script calls the bash script

$cmd = "sh myscript.sh";
$output = array();
$output = shell_exec($cmd);

The script runs fine without the IF statement..

Best Answer

You are calling your bash script with sh. This is usually a basic POSIX shell like dash. The [[ isn't POSIX, it's a bashism (also present in some other shells) so your sh doesn't support it:

$ dash -c "if [[ 10 -gt 8 ]]; then echo yeah; fi"
dash: 1: [[: not found

So, either change your script to use the standard [ (you're not using any special features of [[ anyway):

if [ -e /var/log/apache2/error.log ]; then
    echo YES
fi

Or change your PHP script and call the script with bash explicitly:

$cmd = "bash myscript.sh";

or, since you do have a #!/bin/bash shebang, and assuming the script has the executable bit set, just call it directly:

$cmd = "./myscript.sh";
Related Question