sribasu
sribasu

Reputation: 660

PHP shell_exec() unable to run part of shell script

I have encountered a strange problem. I have created a gitlab custom webhook. The webhook service is written in php (gitlab.php). The php script, when called with proper payload, should start an automated deployment. The deployment script is basically a shell script (deploy.sh)

Code of gitlab.php

<?php
$json = file_get_contents('php://input');
// Converts it into a PHP object
$data = json_decode($json, true);
$secret = "";
foreach (getallheaders() as $name => $value) { 
    if($name=='X-Gitlab-Token') {
        $secret = $value;
    }
}

if($secret=="mysecretcode" && $data['object_kind']=="push") {
    file_put_contents("/opt/lampp/htdocs/autodeploy/autodeploy.log", "Webhook auto deployment started at ". date("Y-m-d H:i:s") . "\n". shell_exec("sh /opt/lampp/htdocs/autodeploy/deploy.sh")."\n**********************************************\n\n", FILE_APPEND);
    die("Deployment success");
}
else {
 die("Auth token invalid or no triggerable event found");
}
?>

Code of deploy.sh

#!/bin/bash
cd "/opt/lampp/htdocs/nodejs/myapp"
echo "Stopping application..."
forever stop index.js
cd ..
sudo rm -rf myapp
echo "Pulling latest code from gitlab..."
git clone -b "master" https://myusername%40domain.com:[email protected]/myusername/myapp.git
cd myapp
echo "Installing dependencies..."
npm install
echo "Starting application..."
forever start index.js
echo "Application started on port 3000."

When I push code to gitlab, it triggers the webhook and initiates the deployment process and I see my webhook file gitlab.php returned success response to Gitlab and has written following output in autodeploy.log file

Webhook auto deployment started at 2021-10-03 13:32:07
Stopping application...
Pulling latest code from gitlab...
Installing dependencies...
Starting application...
Application started on port 3000.

**********************************************

But, the deployment actually never happens. It just runs the echo statements (and may be cd, rm etc as well) and rest of the shell commands are kind of ignored or not executed. It for sure doesn't run the git clone command, because I do not see latest code getting refreshed on my server from gitlab. Not sure though what happens to the npm and forever commands.

By the way, this is a Ubuntu VPS server with latest ApacheFriends XAMPP server installed, php v8. All the three files mentioned above reside at the same path i.e. /opt/lampp/htdocs/autodeploy and my deploy.sh script tries to deploy a separate nodejs application in /opt/lampp/htdocs/nodejs/myapp folder. Strangely enough, when I run deploy.sh directly from terminal it deploys the latest code successfully. Which means, all the statements in the script gets executed as expected. It only fails when executed from the php script using shell_exec() function.

Any clue what could be the reason?

Upvotes: 0

Views: 321

Answers (1)

LeGEC
LeGEC

Reputation: 51780

The documentation for shell_exec doesn't state it clearly, but chances are you only get the stdout of your command, not its stderr -- the first comment certainly seems to indicate that, it would also match the "it's the same thing as backtick" decription.
If such is the case, you simply don't have the error messages in your output.

Try running :

shell_exec("sh .../deploy.sh 2>&1")

I also second @phd's suggestion (in the comments to your question) : turn set -e on, at least your script will halt when you get an error.
Chances are your current script would fail at the first line : cd "/opt/lampp/htdocs/nodejs/myapp".

I also strongly advise to drop the sudo in sudo rm -rf ....

Upvotes: 1

Related Questions