无法通过 PHP 脚本执行 gradle 包装器脚本

can't execute a gradle wrapper script through a PHP script

我会尽量简要说明我要完成的工作。

我想在这里做的是,我想制作一个 webApp,它可以根据用户输入自动构建 android 应用程序 (APK)。

我正在 运行 安装一个 CLI Ubuntu Linux 服务器 (18.04.1),它在

上安装了 LAMP 堆栈

对于阿帕奇:

$ apache2 -v 
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2021-06-18T11:06:22

对于PHP:

$ php -v
PHP 7.4.21 (cli) (built: Jul  1 2021 16:09:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.21, Copyright (c), by Zend Technologies

对于MySQL

$ sudo mysql -v -u mysql_username -p
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 48
Server version: 5.7.34-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

我创建了一个目录(/var/www/my_webapp.com/),我的 webApp 所在的目录如下:

.
├── build.sh
├── Source
│   ├── app
│   ├── build.gradle
│   ├── gradle
│   ├── .gradle
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── local.properties
│   └── settings.gradle
└── test.php

build.sh脚本负责调用gradle包装器并启动构建过程,如下所示:

cd /var/www/my_webapp.com/Source/ && ./gradlew assembleDebug

Source 目录是一个文件夹,其中包含我们要构建并编译为 APK 的 android 应用源代码。

最后但同样重要的是,test.php 脚本为 bash 脚本 (build.sh) 发出命令以构建 APK。如下所示:

<?php
/**
 * Execute the given command by displaying console output live to the user.
 *  @param  string  cmd          :  command to be executed
 *  @return array   exit_status  :  exit status of the executed command
 *                  output       :  console output of the executed command
 */
function liveExecuteCommand($cmd) {

    while (@ ob_end_flush()); // end all output buffers if any

    $old_directory = getcwd();
    chdir("Source/");

    $proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');

    $live_output     = "";
    $complete_output = "";

    echo "<pre>";
    while (!feof($proc)) {
        $live_output     = fread($proc, 4096);
        $complete_output = $complete_output . $live_output;
        echo $live_output . "\n";
        @ flush();
    }
    echo "</pre>";

    pclose($proc);

    // get exit status
    preg_match('/[0-9]+$/', $complete_output, $matches);

    chdir($old_directory);

    // return exit status and intended output
    return array ('exit_status'  => intval($matches[0]),
                    'output'       => str_replace("Exit status : " . $matches[0], '', $complete_output)
                );
}

$result = liveExecuteCommand(dirname(__FILE__) . '/build.sh');


if($result['exit_status'] === 0){
    echo "finished sucessfully. <br /> ";
} else {
    echo "finished with error: {$result['output']} <br /> ";
}

问题是当我尝试 运行 php 脚本 - test.php 即 - 时,我收到此错误:

finished with error:
Exception in thread "main" java.lang.RuntimeException: Could not create parent directory for lock file /var/www/.gradle/wrapper/dists/gradle-6.5-bin/6nifqtx7604sqp1q6g8wikw7p/gradle-6.5-bin.zip.lck
    at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:43)
    at org.gradle.wrapper.Install.createDist(Install.java:48)
    at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
    at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)

当我尝试在终端中手动 运行 build.sh 脚本时,它 运行 没问题并生成了 APK。

我不知道为什么 gradle 构建脚本会尝试在路径中创建一个目录,如前一个错误消息所示,知道构建脚本驻留在一个完全不同的目录中(/var/www/my_webapp.com)

看来问题是权限问题,因为执行脚本的用户 www-data 来自 Apache。所以我所要做的就是使用以下命令递归地将目录的所有者更改为 www-data :

$ sudo chown -R www-data my_webapp.com/ 

而且效果很好。