php - PHP shell_exec() 无法运行部分 shell 脚本
问题描述
我遇到了一个奇怪的问题。我创建了一个 gitlab 自定义 webhook。webhook 服务是用 php (gitlab.php) 编写的。当使用适当的有效负载调用 php 脚本时,应该会开始自动部署。部署脚本基本上是一个 shell 脚本(deploy.sh)
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");
}
?>
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:MyEncodedPass123@gitlab.com/myusername/myapp.git
cd myapp
echo "Installing dependencies..."
npm install
echo "Starting application..."
forever start index.js
echo "Application started on port 3000."
当我将代码推送到 gitlab 时,它会触发 webhook 并启动部署过程,我看到我的 webhook 文件 gitlab.php 向 Gitlab 返回了成功响应,并在 autodeploy.log 文件中写入了以下输出
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.
**********************************************
但是,部署实际上从未发生过。它只是运行echo
语句(也可能是cd
,rm
等等),其余的 shell 命令被忽略或不执行。它肯定不会运行该git clone
命令,因为我没有看到 gitlab 在我的服务器上刷新了最新代码。不确定npm
andforever
命令会发生什么。
顺便说一下,这是一个 Ubuntu VPS 服务器,安装了最新的 ApacheFriends XAMPP 服务器,php v8。上面提到的所有三个文件都位于同一路径/opt/lampp/htdocs/autodeploy
,即我的 deploy.sh 脚本尝试在/opt/lampp/htdocs/nodejs/myapp
文件夹中部署一个单独的 nodejs 应用程序。奇怪的是,当我直接从终端运行 deploy.sh 时,它会成功部署最新的代码。这意味着,脚本中的所有语句都按预期执行。它仅在使用 shell_exec() 函数从 php 脚本执行时才会失败。
任何线索可能是什么原因?
解决方案
的文档shell_exec
没有清楚地说明它,但很可能你只得到stdout
你的命令,而不是它stderr
-第一条评论当然似乎表明,它也将匹配“它与反引号相同”的描述。
如果是这种情况,您的输出中根本没有错误消息。
尝试运行:
shell_exec("sh .../deploy.sh 2>&1")
我还支持@phd 的建议(在对您问题的评论中):打开set -e
,至少当您遇到错误时您的脚本会停止。
您当前的脚本可能会在第一行失败:cd "/opt/lampp/htdocs/nodejs/myapp"
。
我也强烈建议放弃sudo
.sudo rm -rf ...
推荐阅读
- amazon-elastic-beanstalk - AWS Beanstalk 中的 Rails 6 凭证:ArgumentError: key must be 16 bytes
- android - 期待 BroadcastReceiver 的成员声明
- python - 如何在带有动态 btn 的两个列表框和带有 Tkinter 的列表框之间移动项目?
- apk - 在 google play 控制台中发布 APK 时出现此错误 此 APK 将不会提供给任何用户,因为它完全被隐藏了
- virtual-machine - Hyper-V 上的 Linux VHDX 大小
- flutter - Flutter - StreamBuilder - Api - 页面刷新
- php - PHPMailer:没有错误但不在实时服务器上发送邮件(php)
- php - Laravel Echo 服务器在浏览器中没有响应
- windows - 无法在 WinXP 中调用 StrFormatByteSize64?
- git - 如何撤消 git checkout 文件名