php exec SVN 空输出,在同一用户下的终端中工作正常

php exec SVN empty output, works fine in terminal under same user

我在 PHP 中更新 SVN 时遇到问题。本来好好的,几天前突然不工作了。

我正在通过 Nginx 运行宁 PHP-FPM 5.5。 SVN版本为1.8.8.

代码:

exec("svn cleanup $path");
exec("svn revert $path -R");
exec("svn update $path --accept theirs-full --non-interactive", $output, $return);
echo "Return: $return\nOutput: ".print_r($output, true)

输出:

Return: 1
Output: Array
(
)

当我在终端中 运行 时(在与 PHP-FPM 和 Nginx 相同的用户下),我得到了预期的输出:

Updating '/path/to/app':
At revision 100

PHP CLI 也可以使用正确的输出(在与 PHP-FPM 和 Nginx 相同的用户下):

php5 /path/to/app/svnupdate.php

基于此,svn 上的 PHP5-FPM exec 似乎是一个特别的问题。但是我怎样才能调试它并找出问题所在呢?

谢谢。

来自评论的更新以将所有内容整合在一起: 尝试了 proc_open 方法,运行 只通过 "svn cleanup $path" 失败并导致所有文件锁定。 运行在终端中同一用户下执行相同的命令工作正常并再次解锁所有文件。

尝试了 svn bin 的完整路径,没有区别

运行 "svn info $path" 似乎工作正常,没有文件被锁定。 以下命令都在 php exec/proc_open 中失败(没有任何错误消息或输出)并锁定应用程序文件:

"svn update $path" returns "Updating '$path'" 但到此为止,之前当前版本号将在第二行返回。

我有第二个设置,使用不同的应用程序和 svn 服务器,但 运行 使用相同的版本 OS 和所有软件,这个工作正常。我认为这排除了软件。

我尝试将问题服务器回滚到 2 个月前运行时的版本,服务器在启动时自动更新软件和应用程序,但不应该触及配置文件或缓存。可用后,它仍然显示相同的问题。相当确定排除了软件配置 files/cache。

这只留下应用程序代码库和 svn 服务器作为可能的原因。我接下来会尝试重置 svn 服务器并重做 svn 项目。

更新二: 在 SVN 服务器上重新创建项目,从应用服务器和所有 svn 配置目录中删除应用程序,从 SVN 服务器(构建 1)检出新项目。仍然是同样的错误。 !_!

更新 3: 完成上述所有操作后,我得出结论,只留下了可能导致问题的文件库。而且,由于一些文件名中包含特殊字符,SVN 抛出了 "Can't convert string from native encoding to 'UTF-8':" 错误。有趣的是,该错误仅在 运行 从 php-fpm 而不是在终端中时停止了该过程。不知道为什么。我添加了 export LC_CTYPE=en_US.UTF-8;到 exec 命令,现在它工作正常。

exec("export LC_CTYPE=en_US.UTF-8; svn update $path",$output);

exit status (1) indicates that the command fails for some reason. To find out the reason, you need to capture the standard error with the help of proc_open function as shown in exec 函数只捕获标准输出。

SVN 抛出 "Can't convert string from native encoding to 'UTF-8':" 错误,因为一些文件的文件名中包含特殊字符。有趣的是,该错误仅在来自 php-fpm 而不是终端中的 运行 时停止了进程。不知道为什么。我添加了 export LC_CTYPE=en_US.UTF-8;到 exec 命令,现在它工作正常。

exec("export LC_CTYPE=en_US.UTF-8; svn update $path",$output);

我用这段代码实际发现了php中的错误:

$proc = proc_open('svn update', $desc, $pipes);
echo 'PIPE 1: '.stream_get_contents($pipes[1]); fclose($pipes[1]);
echo 'PIPE 2: '.stream_get_contents($pipes[2]); fclose($pipes[1]);
echo 'STATUS: '.proc_close($proc);

在我的情况下,我通过以下步骤解决了问题:

  1. 查看哪个用户php-fpm 运行,我的是nginx

  2. cat /etc/passwd检查'nginx'用户,它的主目录是'/var/cache/nginx'

  3. cp /root/.subversion 到 /var/cache/nginx

  4. 重新配置 /var/cache/nginx/.subversion/servers 如果需要

  5. 那么效果很好

也许调试过程有帮助:

  1. 估计是权限问题

  2. 我把nginx/sbin/nologin改成了/bin/bash

  3. 我运行runuser -l nginx -c 'php myphpscript_which_exec_svn_command.php'

  4. 会输出一些你需要的信息

  5. 所以我得到了解决方案,出于安全原因,将nginx用户属性改回(/bin/bash/sbin/nologin