2016-10-11 3 views
0

を使用している間、私たちはこのような何かを行うことができますファイルハンドルはstdoutと指定されています。これは、このシェルのコマンドと同じです。 リダイレクトPHPのexecの(または類似の機能)Pythonで

grep -E foo /root/text | sed -E 's/bar/baz/g' > /tmp/whatever 

私はPHPでこの動作を再現したいと思いますが、同等のネイティブ機能を見つけることではないのです。私が行ってきたことは、長い文字列として同等のシェルコマンドを構築し、shell_exec()にそれを渡すことですが、これは特にescapeshellarg()の正しい使い方と、乱雑である(上記のPythonコードで必要とされていないノートエスケープ。)

$pattern = "foo"; 
$searchfile = "/root/text"; 
$search  = "bar"; 
$replace = "baz"; 

$tempfile = tempnam(sys_get_temp_dir(), 'asdf'); 
$grepcmd = "/bin/grep -E " . escapeshellarg($pattern) . " " . escapeshellarg($searchfile); 
$sedcmd  = "/bin/sed -E " . escapeshellarg("s/$search/$replace/g"); 
exec("$grepcmd | $sedcmd > $tempfile); 

各コマンドを別々に実行し、出力を変数に取り込み、次のコマンドに渡すこともできますが、これは明らかに非効率的です。

PHPでこれと似たようなことを行うネイティブな方法はありますか、それとも私の現在の方法はそれほど良いものですか?

答えて

1

proc_openとそれに関連する機能を使用できます。

$descriptorSpec = [ 
    0 => ['pipe', 'r'], // stdin 
    1 => ['pipe', 'w'], // stdout 
    2 => ['pipe', 'w'], // stderr 
]; 

$process = proc_open($cmd, $descriptorSpec, $pipes); 

if (!is_resource($process)) { 
    throw new Exception('Unable to start shell process.'); 
} 

$out = stream_get_contents($pipes[1]); 
fclose($pipes[1]); 

$error = stream_get_contents($pipes[2]); 
fclose($pipes[2]); 

$status = proc_close($process); 
if ($status !== 0) { 
    throw new Exception('Command ' . $cmd . ' returned code ' . $status . '. Output: ' . $error); 
} 

あなたが最初のコマンドからの出力を使用する場合は、他のコマンドの標準入力記述子に結果パイプのいずれかを渡す:あなたは、ファイルに記述子の1をリダイレクトしたい場合は

​​

fopen()から入手できるリソースを提供してください:

$res = fopen('file.log', 'w+'); 
$descriptorSpec = [ 
    0 => ['pipe', 'r'], // stdin 
    1 => $res, // stdout 
    2 => $res, // stderr 
]; 
+0

これは有望なスタートアップのようです。いくつかの戻り値(mysqldumpからの非常に大きな出力、gzipへの出力など)では、 'proc_open()'の次のインスタンスに渡すだけの変数を作成することは非常に非効率的です。 – miken32

関連する問題