Всем привет! Подскажите вот какую вещь: Есть папка с проектом. В ней в коре проинициализирован git-репозиторий. Хочу сделать так, чтобы можно было из PHP-скрипта вызывать команду git status - чтобы можно было видеть, какие файлы были изменены/ добавлены. Сейчас у меня вот так реализовано: PHP: $output = null; $resultCode = null; exec('git status', $output, $resultCode); Debuger::dbgLog($output,'_COMMAND_EXEC_'); Debuger::dbgLog пишет в txt-файл данные из $output Если открыть лог-файл, то там будет записан пустой массив: PHP: 2024-09-24 19:25:28 Array ( ) Если выполнить команду PHP: exec('whoami', $output, $resultCode); то в лог-файл пишутся корректные данные, то есть exec нормально отрабатывает. Подскажите, что я делаю не так? Почему команда git status не отрабатывает при использовании функции exec? Само собой git установлен, и из командной строки git status работает.
Есть у PHP веселушки и приколы с запуском скриптов через exec. Он то PATH криво считает на винде, то изменения в нем не сохранит, то вывод неизвестно куда отправит... Наверное самый простой путь без гугления и экспериментов функцией `proc_open` это: 1. установите composer (на оф. сайте инструкция) - композер это еще один exe файл (такой же как и PHP) который использует язык PHP чтобы скачивать из интернета готовые пакеты других людей с сайта https://packagist.org 2. в консоли в папке с "проектом" или в пустой папке напишите Код (Text): composer require symfony/process 3. запускайте вашу команду файлом с вот таким кодом: Код (Text): // index.php // подключаем пакеты композера в наш скрипт (в папке `vendor` будет лежать скачанный из интернета `symfony/process`) require_once __DIR__ . '/vendor/autoload.php'; $process = new \Symfony\Component\Process\Process(['ls', '-lsa']); $process->run(); // executes after the command finishes if (!$process->isSuccessful()) { throw new \Symfony\Component\Process\Exception\ProcessFailedException($process); } echo $process->getOutput(); 4. в консоли `php index.php` Просто в этой библиотеке от разработчиков symfony уже многие шишки учтены и зафикшены. На уровне всего языка оно не поправится, т.к. фишки происходят на разных сборках винды в разное время, и в основном связаны с неверной настройкой системы, которая теоритически, значит, должна производится сотрудниками майкрософт. Это не значит, что винда плохая, это значит что её обновы - её крест. Пс. я понимаю что у вас linux, судя по команде `whoami`, но кто его знает как оно там отрабатывает, symfony/process точно железнее и стабильнее, хотя под капотом оно же.
У меня первая версия - проверить пользователя и права. Предположу, что разовое выполнение команды идёт от пользователя, под которым вы в системе, а при выполнении web-запроса - от пользователя веб-сервера: www-data или другого, специального. Возможно под другим пользователем git не работает?
А вот это уже можно проверить с помощью proc_open Код (Text): <?php $h = proc_open('git status', [ [ 'pipe', 'r ], [ 'file', __DIR__ . '/stdout.txt', 'a' ] [ 'file', __DIR__ . '/stderr.txt', 'a' ] ], $pipes); proc_close($h); И посмотреть на содержимое обоих файлов через тот или иной метод запуска. В stderr.txt может быть ответ
Попробовал вариант, который предложил gzhegow Установил composer, потом добавил код: Код (Text): // index.php // подключаем пакеты композера в наш скрипт (в папке `vendor` будет лежать скачанный из интернета `symfony/process`) require_once __DIR__ . '/vendor/autoload.php'; $process = new \Symfony\Component\Process\Process(['ls', '-lsa']); $process->run(); // executes after the command finishes if (!$process->isSuccessful()) { throw new \Symfony\Component\Process\Exception\ProcessFailedException($process); } echo $process->getOutput(); Вариант с $process = new \Symfony\Component\Process\Process(['ls', '-lsa']); отрабатывает хорошо. Потом я попробовал вариант $process = new \Symfony\Component\Process\Process(['git', 'status']); - появляется ошибка: Код (Text): [Symfony\Component\Process\Exception\ProcessFailedException] The command "'git' 'status'" failed. Exit Code: 128(Invalid exit argument) Working directory: /home/bitrix/www/bitrix/admin Output: ================ Error Output: ================ fatal: not a git repository (or any of the parent directories): .git То есть выполнение страницы вроде как прерывается, и отображается эта ошибка, но в конце также выводится именно то, что я и ожидал увидеть, а именно: Код (Text): fatal: not a git repository (or any of the parent directories): .git Прям то, что я и получал, выполняя команду непосредственно на сервере. Почему то объект \Symfony\Component\Process\Process проглатывает команду ls -lsa Но не проглатывает git status
предположу, что гит репозиторий у вас не тут: /home/bitrix/www/bitrix/admin/ а вот тут /home/bitrix/www/bitrix/ А скрипт лежит в /home/bitrix/www/bitrix/admin/ Вы хоть запускаете скрипт не через браузер? Можно конечно и через браузер да, только удобнее же в консоли писать `php script.php` и получать ответ, чем надеятся что всё печатаемое-непечатаемое попало в браузер на вывод. И потом - под браузер из коробки обычно другие настройки папок, окружения, прав чтения и так далее.
Я посмотрел с помощью WinSCP - в папке /home/bitrix/www/bitrix нет репозитория. Там нет папки .git Да и в /home/bitrix/www/bitrix/admin/ тоже нет папки .git Тогда странно почему мне вообще в терминале выводится ответ Код (Text): fatal: not a git repository (or any of the parent directories): .git Походу на сервере в VMBitrix просто установлен git, но не проинициализирован репозиторий. Сейчас попробую...
Потому что git устанавливается глобально и попытка вызвать его в любой папке все равно проходит через программу git
В общем проинициализировал я репозиторий в папке /home/bitrix/www Пробую выполнить скрипт Код (Text): require_once __DIR__ . '/vendor/autoload.php'; $process = new \Symfony\Component\Process\Process(['ls', '-lsa']); $process->run(); if (!$process->isSuccessful()) { throw new \Symfony\Component\Process\Exception\ProcessFailedException($process); } echo $process->getOutput(); Получаю ответ: Код (Text): [Symfony\Component\Process\Exception\ProcessFailedException] The command "'git' 'status'" failed. Exit Code: 128(Invalid exit argument) Working directory: /home/bitrix/www/bitrix/admin Output: ================ Error Output: ================ fatal: detected dubious ownership in repository at '/home/bitrix/www' To add an exception for this directory, call: git config --global --add safe.directory /home/bitrix/www (0) Пробовал выполнить команду git config --global --add safe.directory /home/bitrix/www и уже потом скрипт запустить - ошибка не уходит. Также выполнял команду Код (Text): git config --global --add safe.directory '*' Тоже самое - скрипт падает, и ошибка остается. А если в консоли выполнить git status - команда нормально отрабатывает --- Добавлено --- Место, где лежит сам скрипт вот тут: local\modules\mycompany.files\lib\event\files.php
Причина видимо в том, что владелец файлов не совпадает с аккаунтом, под которым исполняются web-скрипты. Ты можешь попробовать вылечить причину, а не заглушать симптомы. Но с симтомами возможно поможет рецепт SO https://stackoverflow.com/a/73100228