获取从命令所有的bash子shell在PHP

问题描述:

我需要检测,如果一个命令在它的子命令一个有sudo命令,到目前为止,我有这样的:获取从命令所有的bash子shell在PHP

public function split_command($command) { 
    // this regex is not perfect but work 
    $separators = "/(?:\"[^\"\\\\]*(?:\\\\[\S\s][^\"\\\\]*)*\"|'[^'\\\\]*(?:\\\\[\S\s][^'\\\\]*)*')(*SKIP)(*F)|(\s+(?:&&|\|{1,2}|;)\s+)/"; 
    $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE; 
    return preg_split($separators, $command, null, $flags); 
} 
public function have_sudo($command) { 
    $re = "!^(sudo|" . shell_exec("which sudo") . ")!"; 
    foreach ($this->split_command($command) as $part) { 
     if (preg_match($re, trim($part))) { 
      return true; 
     } 
    } 
} 

但如果失败则是命令如下所示: echo `sudo whoami`。我如何解析命令以获取子shell列表。

也应该对命令的工作是这样的:

$(some command; `other command (different command) $(some command)`) 

它应该返回数组:

["some command; `other command (different command) $(some command)`", 
"`other command (different command) $(some command)", 
"different command", "some command"] 

所以我可以递归调用have_sudo阵列中的每个元素的另一种选择是回归大多数来自命令的外部子壳体。

+0

[正则表达式不可能被用于(任意和正确的)解析(https://*.com/q/1732348)(这适用于HTML作为以及编程语言)。你需要一个解析器。 – Siguza

我已经创建了一个解析器:

public function get_subshells($command) { 
    $re = '/(\$\(|\(|\)|`)/'; 
    $parts = preg_split($re, $command, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 
    $subshells = array(); 
    $backtick = false; 
    $stack = array(); 
    foreach ($parts as $part) { 
     if (preg_match($re, $part)) { 
      if ($part == "`") { 
       $backtick = !$backtick; 
      } 
      if ($backtick || preg_match("/\(/", $part)) { 
       $stack[] = array('tag' => $part, 'content' => ''); 
      } else { 
       $last = array_pop($stack); 
       $subshells[] = preg_replace('/^(\$\(|\(|`)/', '', $last['content']); 
      } 
     } 
     if (count($stack) > 0) { 
      foreach ($stack as &$subshell) { 
       $subshell['content'] .= $part; 
      } 
     } 

    } 
    return array_reverse($subshells); 
}