За последние 24 часа нас посетили 17017 программистов и 1835 роботов. Сейчас ищут 1020 программистов ...

Запуск произвольной команды из PHP кода

Тема в разделе "PHP для профи", создана пользователем fenix_63, 24 сен 2024.

  1. fenix_63

    fenix_63 Активный пользователь

    С нами с:
    16 мар 2015
    Сообщения:
    11
    Симпатии:
    0
    Адрес:
    Тольятти
    Всем привет!

    Подскажите вот какую вещь:

    Есть папка с проектом. В ней в коре проинициализирован git-репозиторий.

    Хочу сделать так, чтобы можно было из PHP-скрипта вызывать команду git status - чтобы можно было видеть, какие файлы были изменены/ добавлены.

    Сейчас у меня вот так реализовано:

    PHP:
    1. $output = null;
    2. $resultCode = null;
    3. exec('git status', $output, $resultCode);
    4. Debuger::dbgLog($output,'_COMMAND_EXEC_');

    Debuger::dbgLog пишет в txt-файл данные из $output

    Если открыть лог-файл, то там будет записан пустой массив:

    PHP:
    1. 2024-09-24 19:25:28
    2. (
    3. )
    Если выполнить команду

    PHP:
    1. exec('whoami', $output, $resultCode);

    то в лог-файл пишутся корректные данные, то есть exec нормально отрабатывает.

    Подскажите, что я делаю не так? Почему команда git status не отрабатывает при использовании функции exec?

    Само собой git установлен, и из командной строки git status работает.
     
  2. gzhegow

    gzhegow Новичок

    С нами с:
    28 апр 2024
    Сообщения:
    16
    Симпатии:
    0
    Есть у PHP веселушки и приколы с запуском скриптов через exec. Он то PATH криво считает на винде, то изменения в нем не сохранит, то вывод неизвестно куда отправит...

    Наверное самый простой путь без гугления и экспериментов функцией `proc_open` это:

    1. установите composer (на оф. сайте инструкция) - композер это еще один exe файл (такой же как и PHP) который использует язык PHP чтобы скачивать из интернета готовые пакеты других людей с сайта https://packagist.org

    2. в консоли в папке с "проектом" или в пустой папке напишите
    Код (Text):
    1. composer require symfony/process
    3. запускайте вашу команду файлом с вот таким кодом:
    Код (Text):
    1.  
    2. // index.php
    3.  
    4. // подключаем пакеты композера в наш скрипт (в папке `vendor` будет лежать скачанный из интернета `symfony/process`)
    5. require_once __DIR__ . '/vendor/autoload.php';
    6.  
    7. $process = new \Symfony\Component\Process\Process(['ls', '-lsa']);
    8. $process->run();
    9.  
    10. // executes after the command finishes
    11. if (!$process->isSuccessful()) {
    12.     throw new \Symfony\Component\Process\Exception\ProcessFailedException($process);
    13. }
    14.  
    15. echo $process->getOutput();
    4. в консоли `php index.php`

    Просто в этой библиотеке от разработчиков symfony уже многие шишки учтены и зафикшены.

    На уровне всего языка оно не поправится, т.к. фишки происходят на разных сборках винды в разное время, и в основном связаны с неверной настройкой системы, которая теоритически, значит, должна производится сотрудниками майкрософт. Это не значит, что винда плохая, это значит что её обновы - её крест.

    Пс. я понимаю что у вас linux, судя по команде `whoami`, но кто его знает как оно там отрабатывает, symfony/process точно железнее и стабильнее, хотя под капотом оно же.
     
    #2 gzhegow, 8 окт 2024
    Последнее редактирование: 8 окт 2024
  3. romt

    romt Активный пользователь

    С нами с:
    26 ноя 2020
    Сообщения:
    9
    Симпатии:
    0
    У меня первая версия - проверить пользователя и права.

    Предположу, что разовое выполнение команды идёт от пользователя, под которым вы в системе,
    а при выполнении web-запроса - от пользователя веб-сервера: www-data или другого, специального. Возможно под другим пользователем git не работает?
     
  4. gzhegow

    gzhegow Новичок

    С нами с:
    28 апр 2024
    Сообщения:
    16
    Симпатии:
    0
    А вот это уже можно проверить с помощью proc_open
    Код (Text):
    1. <?php
    2.  
    3. $h = proc_open('git status', [
    4.   [ 'pipe', 'r ],
    5.   [ 'file', __DIR__ . '/stdout.txt', 'a' ]
    6.   [ 'file', __DIR__ . '/stderr.txt', 'a' ]
    7. ], $pipes);
    8.  
    9. proc_close($h);
    И посмотреть на содержимое обоих файлов через тот или иной метод запуска.
    В stderr.txt может быть ответ
     
  5. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.575
    Симпатии:
    1.759
    Он не exe, хотя и не страшно
     
  6. gzhegow

    gzhegow Новичок

    С нами с:
    28 апр 2024
    Сообщения:
    16
    Симпатии:
    0
    Ой, косячок, он `php` который запускается с помощью `cmd`
     
  7. fenix_63

    fenix_63 Активный пользователь

    С нами с:
    16 мар 2015
    Сообщения:
    11
    Симпатии:
    0
    Адрес:
    Тольятти
    Попробовал вариант, который предложил gzhegow

    Установил composer, потом добавил код:

    Код (Text):
    1. // index.php
    2. // подключаем пакеты композера в наш скрипт (в папке `vendor` будет лежать скачанный из интернета `symfony/process`)
    3. require_once __DIR__ . '/vendor/autoload.php';
    4. $process = new \Symfony\Component\Process\Process(['ls', '-lsa']);
    5. $process->run();
    6. // executes after the command finishes
    7. if (!$process->isSuccessful()) {
    8.     throw new \Symfony\Component\Process\Exception\ProcessFailedException($process);
    9. }
    10. echo $process->getOutput();
    Вариант с $process = new \Symfony\Component\Process\Process(['ls', '-lsa']); отрабатывает хорошо.
    Потом я попробовал вариант $process = new \Symfony\Component\Process\Process(['git', 'status']); - появляется ошибка:

    Код (Text):
    1. [Symfony\Component\Process\Exception\ProcessFailedException]
    2. The command "'git' 'status'" failed.
    3.  
    4. Exit Code: 128(Invalid exit argument)
    5.  
    6. Working directory: /home/bitrix/www/bitrix/admin
    7.  
    8. Output:
    9. ================
    10.  
    11.  
    12. Error Output:
    13. ================
    14. fatal: not a git repository (or any of the parent directories): .git
    То есть выполнение страницы вроде как прерывается, и отображается эта ошибка, но в конце также выводится именно то, что я и ожидал увидеть, а именно:

    Код (Text):
    1. fatal: not a git repository (or any of the parent directories): .git
    Прям то, что я и получал, выполняя команду непосредственно на сервере.

    Почему то объект \Symfony\Component\Process\Process проглатывает команду ls -lsa
    Но не проглатывает git status
     
  8. gzhegow

    gzhegow Новичок

    С нами с:
    28 апр 2024
    Сообщения:
    16
    Симпатии:
    0
    предположу, что гит репозиторий у вас не тут:
    /home/bitrix/www/bitrix/admin/
    а вот тут
    /home/bitrix/www/bitrix/

    А скрипт лежит в
    /home/bitrix/www/bitrix/admin/

    Вы хоть запускаете скрипт не через браузер? Можно конечно и через браузер да, только удобнее же в консоли писать `php script.php` и получать ответ, чем надеятся что всё печатаемое-непечатаемое попало в браузер на вывод. И потом - под браузер из коробки обычно другие настройки папок, окружения, прав чтения и так далее.
     
  9. fenix_63

    fenix_63 Активный пользователь

    С нами с:
    16 мар 2015
    Сообщения:
    11
    Симпатии:
    0
    Адрес:
    Тольятти
    Я посмотрел с помощью WinSCP - в папке /home/bitrix/www/bitrix нет репозитория. Там нет папки .git

    Да и в /home/bitrix/www/bitrix/admin/ тоже нет папки .git
    Тогда странно почему мне вообще в терминале выводится ответ

    Код (Text):
    1. fatal: not a git repository (or any of the parent directories): .git
    Походу на сервере в VMBitrix просто установлен git, но не проинициализирован репозиторий. Сейчас попробую...
     
  10. gzhegow

    gzhegow Новичок

    С нами с:
    28 апр 2024
    Сообщения:
    16
    Симпатии:
    0
    Потому что git устанавливается глобально и попытка вызвать его в любой папке все равно проходит через программу git
     
  11. fenix_63

    fenix_63 Активный пользователь

    С нами с:
    16 мар 2015
    Сообщения:
    11
    Симпатии:
    0
    Адрес:
    Тольятти
    В общем проинициализировал я репозиторий в папке /home/bitrix/www

    Пробую выполнить скрипт

    Код (Text):
    1. require_once __DIR__ . '/vendor/autoload.php';
    2. $process = new \Symfony\Component\Process\Process(['ls', '-lsa']);
    3. $process->run();
    4.  
    5. if (!$process->isSuccessful()) {
    6.     throw new \Symfony\Component\Process\Exception\ProcessFailedException($process);
    7. }
    8. echo $process->getOutput();

    Получаю ответ:

    Код (Text):
    1. [Symfony\Component\Process\Exception\ProcessFailedException]
    2. The command "'git' 'status'" failed.
    3.  
    4. Exit Code: 128(Invalid exit argument)
    5.  
    6. Working directory: /home/bitrix/www/bitrix/admin
    7.  
    8. Output:
    9. ================
    10.  
    11.  
    12. Error Output:
    13. ================
    14. fatal: detected dubious ownership in repository at '/home/bitrix/www'
    15. To add an exception for this directory, call:
    16.  
    17.     git config --global --add safe.directory /home/bitrix/www
    18. (0)
    Пробовал выполнить команду git config --global --add safe.directory /home/bitrix/www и уже потом скрипт запустить - ошибка не уходит.

    Также выполнял команду
    Код (Text):
    1. git config --global --add safe.directory '*'
    Тоже самое - скрипт падает, и ошибка остается. А если в консоли выполнить git status - команда нормально отрабатывает
    --- Добавлено ---
    Место, где лежит сам скрипт вот тут:
    local\modules\mycompany.files\lib\event\files.php
     

    Вложения:

    • 1.png
      1.png
      Размер файла:
      19,1 КБ
      Просмотров:
      2
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.099
    Симпатии:
    1.243
    Адрес:
    там-сям
    Причина видимо в том, что владелец файлов не совпадает с аккаунтом, под которым исполняются web-скрипты.
    Ты можешь попробовать вылечить причину, а не заглушать симптомы. Но с симтомами возможно поможет рецепт SO
    https://stackoverflow.com/a/73100228