Shell.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework;
  7. use Magento\Framework\Shell\CommandRendererInterface;
  8. /**
  9. * Shell command line wrapper encapsulates command execution and arguments escaping
  10. */
  11. class Shell implements ShellInterface
  12. {
  13. /**
  14. * Logger instance
  15. *
  16. * @var \Psr\Log\LoggerInterface
  17. */
  18. protected $logger;
  19. /**
  20. * @var CommandRendererInterface
  21. */
  22. private $commandRenderer;
  23. /**
  24. * @param CommandRendererInterface $commandRenderer
  25. * @param \Psr\Log\LoggerInterface $logger Logger instance to be used to log commands and their output
  26. */
  27. public function __construct(
  28. CommandRendererInterface $commandRenderer,
  29. \Psr\Log\LoggerInterface $logger = null
  30. ) {
  31. $this->logger = $logger;
  32. $this->commandRenderer = $commandRenderer;
  33. }
  34. /**
  35. * Execute a command through the command line, passing properly escaped arguments, and return its output
  36. *
  37. * @param string $command Command with optional argument markers '%s'
  38. * @param string[] $arguments Argument values to substitute markers with
  39. * @return string Output of an executed command
  40. * @throws \Magento\Framework\Exception\LocalizedException If a command returns non-zero exit code
  41. */
  42. public function execute($command, array $arguments = [])
  43. {
  44. $command = $this->commandRenderer->render($command, $arguments);
  45. $this->log($command);
  46. $disabled = explode(',', str_replace(' ', ',', ini_get('disable_functions')));
  47. if (in_array('exec', $disabled)) {
  48. throw new Exception\LocalizedException(new \Magento\Framework\Phrase('The exec function is disabled.'));
  49. }
  50. exec($command, $output, $exitCode);
  51. $output = implode(PHP_EOL, $output);
  52. $this->log($output);
  53. if ($exitCode) {
  54. $commandError = new \Exception($output, $exitCode);
  55. throw new Exception\LocalizedException(
  56. new \Magento\Framework\Phrase("Command returned non-zero exit code:\n`%1`", [$command]),
  57. $commandError
  58. );
  59. }
  60. return $output;
  61. }
  62. /**
  63. * Log a message, if a logger is specified
  64. *
  65. * @param string $message
  66. * @return void
  67. */
  68. protected function log($message)
  69. {
  70. if ($this->logger) {
  71. $this->logger->info($message);
  72. }
  73. }
  74. }