6 * Execute system command
11 * Sudo command, if the cmd needs escalated privileges
17 * Executable of the cmd
23 * Passthrough cmd output
35 * Return code of cmd run
41 * @param string $command
44 public function __construct($command, $verbose = false) {
45 $this->command
= $command;
46 $this->verbose
= $verbose;
50 * (Re-)set sudo command
53 public function setSu($sudo = false) {
58 * Execute a program with escalated privileges handling interactive password prompt
59 * @param string $command
60 * @param string $output
63 private function suExec($command, &$output, &$status) {
64 if (!($proc = proc_open($command, [STDIN
,["pipe","w"],["pipe","w"]], $pipes))) {
66 throw new Exception("Failed to run {$command}");
70 while (!feof($stdout)) {
71 $R = [$stdout]; $W = []; $E = [];
72 if (!stream_select($R, $W, $E, null)) {
75 $data = fread($stdout, 0x1000);
76 /* only check a few times */
78 if (stristr($data, "password")) {
79 printf("\n%s", $data);
84 $status = proc_close($proc);
90 * @throws \pharext\Exception
92 public function run(array $args = null) {
93 $exec = escapeshellcmd($this->command
);
95 $exec .= " ". implode(" ", array_map("escapeshellarg", (array) $args));
99 $this->suExec(sprintf($this->sudo
." 2>&1", $exec), $this->output
, $this->status
);
100 } elseif ($this->verbose
) {
101 ob_start(function($s) {
105 passthru($exec, $this->status
);
108 exec($exec ." 2>&1", $output, $this->status
);
109 $this->output
= implode("\n", $output);
113 throw new Exception("Command {$this->command} failed ({$this->status})");
118 * Retrieve exit code of cmd run
121 public function getStatus() {
122 return $this->status
;
126 * Retrieve output of cmd run
129 public function getOutput() {
130 return $this->output
;