2016-10-06 3 views
1

일부 시스템 제한 명령을 허용하는 심포니를 사용하여 웹 인터페이스를 구현하고 있습니다. 컨트롤러에서 sudo로 심포니 콘솔 명령을 호출하십시오.

$status = $console->run(new ArrayInput([ 
    'command' => 'system:do-restricted', 
    '--option' => true 
]), $output = new BufferedOutput()); 

거기인가 :이 같은 컨트롤러에서 명령을 호출 한 후

app/console system:do-restricted --option 

그리고 :

더 나은 내가 좋아하는 일부 콘솔 명령을 작성했습니다, 내 코드의 논리를 분리하려면 콘솔 명령의 sudo을 허용하는 방법?

위의 명령을 셸 형식으로 변환하고 프로세스를 사용하는 것이 유일한 방법이라고 생각하면 InputArrayOutputBaffer (+ ansi 색)의 명령 및 표준 출력으로 변환하는 간단한 방법이 있습니까?

결국
+0

는 웹 서버가 sudo는이 있습니까 특권? 그렇지 않다면 아마 그렇지 않을 것입니다. – jcroll

+0

물론 컨트롤러는 sudo 명령을 호출 할 수 없습니다. – jcroll

답변

0

, 나는 심포니의 Console\Application 대신에 사용되는이 클래스를 구현했습니다 :

<?php 

namespace Acme\Model; 

use Symfony\Component\Process\Process; 
use Symfony\Component\Console\Input\ArrayInput; 
use Psr\Log\LoggerAwareInterface; 
use Psr\Log\LoggerAwareTrait; 
use Symfony\Component\Console\Output\OutputInterface; 

final class Console implements LoggerAwareInterface 
{ 
    use LoggerAwareTrait; 

    private $consoleCommand; 

    public function __construct($consoleCommand = 'sudo app/console') 
    { 
     $this->consoleCommand = $consoleCommand; 
    } 

    /** 
    * Create a process for console command. 
    * 
    * @param string $command 
    * @param array[] $argv Same syntax as symfony ArrayInput 
    * 
    * @see Symfony\Component\Console\Input\ArrayInput 
    */ 
    public function process($command, array $argv = []) 
    { 
     $console = escapeshellcmd($this->consoleCommand); 

     $command = escapeshellarg($command); 

     $options = []; 

     $arguments = []; 

     foreach ($argv as $name => $value) { 
      if ('--' === substr($name, 0, 2)) { 
       if (false === $value) { 
        continue; 
       } 
       $option = $name; 
       if (is_string($value)) { 
        $option .= '='.$value; 
       } 
       $options[] = escapeshellarg($option); 
      } else { 
       $arguments[] = escapeshellarg($value); 
      } 
     } 

     $process = new Process(
      $console.' ' 
      .$command.' ' 
      .implode(' ', $options).' ' 
      .implode(' ', $arguments) 
     ); 

     if ($this->logger) { 
      $this->logger->info(sprintf('Created process for command: %s', $process->getCommandLine())); 
     } 

     return $process; 
    } 

    /** 
    * Run a console command. 
    * 
    * @param string    $command One of the 'app/console' commands 
    * @param array[]    $argv Assoc array '--opt' => true/false, '--opt' => 'value' or 'arg_name' => 'arg_value' 
    * @param OutputInterface|null $output Output object 
    * 
    * @see Symfony\Component\Console\Input\ArrayInput 
    */ 
    public function run($command, array $argv = [], OutputInterface $output = null) 
    { 
     if ($output->isDecorated()) { 
      $argv['--ansi'] = true; 
     } 
     $process = $this->process($command, $argv); 

     $callable = null; 
     if (null !== $output) { 
      $callable = function ($type, $line) use ($output) { 
       $output->writeln($line); 
      }; 
     } 

     $exitCode = $process->run($callable); 

     if ($this->logger) { 
      $this->logger->info(sprintf('Command returned: %d', $exitCode), ['output' => $output]); 
     } 

     return $exitCode; 
    } 
} 

그리고 나는이 같이 호출 :

$status = $this->console->run(
    'balancer:cluster:copy-config', 
    ['--option' => true, '--opt-val' => 'value', 'arg1' => 'value1'], 
    $output = new BufferedOutput() 
); 
관련 문제