linuxscriptingash

cgi-fcgi script is not executing corectly


Im using:

/usr/local/bin # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.7
PRETTY_NAME="Alpine Linux v3.12"

with /bin/ash shell

I have a script which check a status:

#!/bin/sh


full=$(DOCUMENT_URI=/api/$SERVICE_PREFIX/healthz SCRIPT_FILENAME=/app/src/index.php REQUEST_METHOD=GET cgi-fcgi -bind -connect /run/php-fpm/php.sock)

before=${full%$'\r\n\r\n'*}
after=${full#*$'\r\n\r\n'}
stat=$(echo $before | sed 's/.*Status: //' | cut -d " " -f 1)
sub="Status:"


echo "head is: $before"
echo "tail is: $after"
echo "message is: $full"
echo "status is: $stat"
echo "substring is: $sub"
echo "message is: ${sub} ${stat}"



if [[ "$before" == *"$sub"* ]] && [[ "$stat" != "200"]]; then
  exit 1
fi


if [ "$after" != "OK" ]; then
  exit 1
fi

exit

When I execute the script I get response which is correct but if statement doesn't work:

/usr/local/bin # ./liveness_probe1.sh
head is: Status: 300 Multiple Choices
X-Powered-By: PHP/7.4.16
Content-type: text/html; charset=UTF-8
tail is: OK
message is: Status: 300 Multiple Choices
X-Powered-By: PHP/7.4.16
Content-type: text/html; charset=UTF-8

OK
status is: 300
substring is: Status:
message is: Status: 300
/usr/local/bin # echo $?
0

and when I execute just a command I get different response:

/usr/local/bin # DOCUMENT_URI=/api/$SERVICE_PREFIX/healthz SCRIPT_FILENAME=/app/src/index.php REQUEST_METHOD=GET cgi-fcgi -bind -connect /run/php-fpm/php.so
ck
Status: 300 Multiple Choices
X-Powered-By: PHP/7.4.16
Content-type: text/html; charset=UTF-8

OK

Is there any error in this script?


Solution

  • The condition is a syntax error due to the missing white space before the last ]]:

    if [[ "$before" == *"$sub"* ]] && [[ "$stat" != "200" ]]; then
      exit 1
    fi
    

    Use #!/bin/bash if you require bash features (in this case [[). It's kinda silly you do stat=$(echo $before | sed 's/.*Status: //' | cut -d " " -f 1) opposed to echo "$before" | cut -d'' -f2 or wrap it in a function and use built-ins:

    status_code() {
       local v=${1#* }
       echo ${v%% *}
    }
    
    status_code "Status: 300 Multiple Choices"
    

    which would return 300. I would probably not bother testing against "Status:" prefix, if it's wrong, then the 2nd string will almost certainly be as well:

    if [ "$(status_code "$before")" != "200" ] || [ "$after" != "OK" ]
    then
       exit 1
    fi