こんにちは、らいあです。
Dinoのプログラマーは毎日いろんなツールや関数を作って遊んでいます。
僕が今日作ったクラスを紹介しますね!
[19:13:45] ryerの発言:
$cmd = new CommandLine(’rsync’);
$cmd->setOption(’delete’);
$result = $cmd->execute();
なんかこんなライブラリをどっかで見たことあるんだけど
PEARでしたっけ、知ってるしといる?[19:26:38] r_koikeの発言:
PEAR::System_Command ?[22:19:18] ryerの発言:
こういうのがみつからなかったので作った。そんだけ・・・。
本体:
/** * コマンドラインの実行をする簡易ライブラリ。 */ class GunyuCommand { private static $path = array(); private $name; private $options = array(); private $arguments = array(); private $backgroundEnabled = false; private $stdoutEnabled = true; private $stderrEnabled = false; private $stdoutRedirect = null; private $stderrRedirect = null; private $previousPipes = null; /** * コマンド検索パスの追加 * @param string $path ディレクトリ ex)"/usr/local/bin" */ public static function addPath($path) { self::$path[] = $path; } /** * 生成 * @param string $name コマンド名 ex)"mkdir" */ public function __construct($name) { $this->name = $name; } /** * オプションの追加 * @param string $option 1文字ならショートオプションとみなす。 * @param string $arg */ public function addOption($option, $arg=null) { $this->options[] = array('opt'=>$option, 'arg'=>$arg); } /** * オプションの追加 * 引数にずらずらとオプションを並べることができます。 * ※このメソッドではオプションの引数は取れません。 */ public function addOptions() { foreach (func_get_args() as $option) { $this->options[] = array('opt'=>$option, 'arg'=>null); } } /** * 引数の追加 * @param string $arg */ public function addArgument($arg) { $this->arguments[] = $arg; } /** * バックグラウンドで実行する * ※単にコマンドラインの最後に&をつけるだけです。 * ※デフォルトはfalseです * @param boolean $enabled */ public function setBackgroundEnabled($enabled) { $this->backgroundEnabled = $enabled; } /** * 標準出力をふつうに標準出力する * デフォルトはtrueです。falseだと/dev/null行きになります。 * @param boolean $enabled */ public function setStdOutEnabled($enabled) { $this->stdoutEnabled = $enabled; } /** * 標準出力をファイルにリダイレクトする * デフォルトはnullです。 * @param string $file */ public function setStdOutRedirect($file) { $this->stdoutRedirect = $file; } /** * 標準エラー出力を標準出力にリダイレクトする * デフォルトはfalseです。falseだと/dev/null行きになります。 * @param boolean $enabled */ public function setStdErrEnabled($enabled) { $this->stderrEnabled = $enabled; } /** * 標準エラー出力をファイルにリダイレクトする * ※デフォルトはnullです。 * @param string $file */ public function setStdErrRedirect($file) { $this->stderrRedirect = $file; } /** * パイプでつながった新しいGunyuCommandインスタンスを返します。 * * see below: * $this | $cmd * * @return GunyuCommand $cmd */ public function pipe(GunyuCommand $cmd) { $newCmd = clone $cmd; $newCmd->previousPipes = $this; return $newCmd; } /** * 実行 * @return GunyuCommandResult バックグラウンド実行の場合にはnullが返ります。 */ public function execute() { $cmdLine = $this->getCommandLine(); exec($cmdLine, $stdout, $exitCode); return new GunyuCommandResult($exitCode, $stdout); } /** * コマンドラインを返す * 実際のところこれをexecできます。 * @return string */ public function getCommandLine() { $prevCmd = ''; if ($this->previousPipes) { $prevCmd = $this->previousPipes->getCommandLine(). ' | '; } $path = ''; if (self::$path) { foreach (self::$path as $it) { if (is_executable($it.'/'.$this->name)) { $path = $it.'/'; } } } $cmdName = escapeshellcmd($path.$this->name).' '; $cmdOptions = ''; foreach ($this->options as $it) { if (strlen($it['opt']) >= 2) { $h = '--'; $sep = ($it['arg']===null) ? '' : '='; } else { $h = '-'; $sep = ($it['arg']===null) ? '' : ' '; } $cmdOptions .= '"'. $h. escapeshellcmd($it['opt']). $sep. escapeshellcmd($it['arg']). '" '; } $cmdArguments = ''; foreach ($this->arguments as $it) { $cmdArguments .= '"'. escapeshellcmd($it). '" '; } $cmdStdout = ''; if ($this->stdoutRedirect) { $cmdStdout = '>'.'"'.escapeshellcmd($this->stdoutRedirect).'" '; } else if ($this->stdoutEnabled) { $cmdStdout = ''; } else { $cmdStdout = '>/dev/null '; } $cmdStderr = ''; if ($this->stderrRedirect) { $cmdStderr = '2> '.'"'.escapeshellcmd($this->stderrRedirect).'" '; } else if ($this->stderrEnabled) { $cmdStderr = '2>&1 '; } else { $cmdStderr = '2>/dev/null '; } $cmdBg = ''; if ($this->backgroundEnabled) { $cmdBg = '&'; } return trim($prevCmd.$cmdName.$cmdOptions.$cmdArguments.$cmdStdout.$cmdStderr.$cmdBg); } /** * same getCommandLine */ public function __toString() { return $this->getCommandLine(); } } /** * コマンドラインの実行結果。 * イミュータブルオブジェクトです。 */ class GunyuCommandResult { private $exitCode; private $stdout; /** * 生成 * @param int $exitCode 終了コード * @param array $stdout 標準出力 */ public function __construct($exitCode, $stdout) { $this->exitCode = $exitCode; $this->stdout = $stdout; } /** * getExitCode()==EXIT_SUCCESS * @return boolean */ public function isSuccess() { return ($this->exitCode == 0); } /** * 終了コードを返す * @return int */ public function getExitCode() { return $this->exitCode; } /** * 標準出力を文字列で返す * 各行は0x0Aで接続されています。 * @return string */ public function getStdOut() { return join("\x0A", $this->stdout); } /** * 標準出力を1行ずつの配列で返す * @return array */ public function getStdOutAsArray() { return $this->stdout; } }
使いかた:
$cmd1 = new GunyuCommand('ls'); $cmd1->addOptions('a', 'l'); $cmd1->addArgument('/'); $cmd2 = new GunyuCommand('grep'); $cmd2->addArgument('u'); $cmd3 = new GunyuCommand('grep'); $cmd3->addArgument('e'); $cmd4 = new GunyuCommand('grep'); $cmd4->addArgument('l'); $result = $cmd1->pipe($cmd2)->pipe($cmd3)->pipe($cmd4)->execute(); echo $result->getStdOut();
結果:
-rw-r--r-- 1 root root 0 Feb 22 20:40 .autorelabel drwx------ 2 root root 16384 Feb 22 20:31 lost+found drwxr-xr-x 2 root root 4096 Feb 22 20:31 selinux
※こんな感じのコマンドが実行されています:
ls “-a” “-l” “/” 2>/dev/null | grep “u” 2>/dev/null | grep “e” 2>/dev/null | grep “l” 2>/dev/null

コメント / トラックバックはありません
コメントする