<?php
$proc = popen( "ls -l *.php *.txt 2>&1", "r" );
while( $line = fgets( $proc )) {
echo $line;
}
pclose( $proc );
?>
proc_open() を使って、標準入力、標準出力、標準エラー、戻り値を扱う
<?php
$spec = array(
0 => array( "pipe", "r" ),
1 => array( "pipe", "w" ),
2 => array( "pipe", "w" ),
);
$proc = proc_open( "ls -l *.php *.txt", $spec, $pipes );
if( is_resource( $proc )) {
fclose( $pipes[0] );
echo "stdout: " . stream_get_contents( $pipes[1] );
fclose( $pipes[1] );
echo "stderr: " . stream_get_contents( $pipes[2] );
fclose( $pipes[2] );
$ret = proc_close( $proc );
echo "exit: " . $ret . "\n";
}
?>
require "open3"
stdout, stderr, status = Open3.capture3( "ls -l *.rb *.txt" )
puts stdout
puts stderr
puts status.exitstatus
import java.io.*;
public class Process2 {
public Process2() {
try {
final Process proc = Runtime.getRuntime().exec(
new String[] { "ls", "-l", "Process2.java" , "*.txt" });
final StringBuilder sbOut = new StringBuilder();
final StringBuilder sbErr = new StringBuilder();
Thread outThread = readStream( proc.getInputStream(), sbOut );
Thread errThread = readStream( proc.getErrorStream(), sbErr );
proc.waitFor();
outThread.join();
errThread.join();
System.out.println( "stdout: " + sbOut );
System.out.println( "stderr: " + sbErr );
System.out.println( "exit code: " + proc.exitValue());
proc.destroy();
} catch( IOException ex ) {
ex.printStackTrace();
} catch( InterruptedException ex ) {
ex.printStackTrace();
}
}
private Thread readStream( final InputStream stream, final StringBuilder sb ) {
Thread thread = new Thread() {
@Override
public void run() {
try( Reader reader = new InputStreamReader( stream )) {
char[] buf = new char[1024];
int len;
while(( len = reader.read( buf )) >= 0 ) {
sb.append( buf, 0, len );
}
} catch( IOException ex ) {
ex.printStackTrace();
}
}
};
thread.start();
return thread;
}
public static void main( String[] args ) {
new Process2();
}
}
Java では Unix系OS で実行した場合も、コマンドライン引数の * はワイルドカード展開されない。
ls -l “*.txt” のように、クォートで囲って実行したのと同じになる。
ExecutorService と Callable を使うと
import java.io.*;
import java.util.concurrent.*;
public class Process4 {
public Process4() {
ExecutorService pool = Executors.newFixedThreadPool( 2 );
try {
final Process proc = Runtime.getRuntime().exec(
new String[] { "ls", "-l", "Process2.java" , "Process2.txt" });
Future<String> futureOut = pool.submit( new ReadStream( proc.getInputStream()));
Future<String> futureErr = pool.submit( new ReadStream( proc.getErrorStream()));
proc.waitFor();
System.out.println( "stdout: " + futureOut.get());
System.out.println( "stderr: " + futureErr.get());
System.out.println( "exit code: " + proc.exitValue());
proc.destroy();
} catch( IOException ex ) {
ex.printStackTrace();
} catch( ExecutionException ex ) {
ex.printStackTrace();
} catch( InterruptedException ex ) {
ex.printStackTrace();
} finally {
pool.shutdownNow();
}
}
public static void main( String[] args ) {
new Process4();
}
private class ReadStream implements Callable<String> {
private InputStream is = null;
public ReadStream( InputStream is ) {
this.is = is;
}
@Override
public String call() throws IOException {
StringBuilder sb = new StringBuilder();
try( Reader reader = new InputStreamReader( is )) {
char[] buf = new char[1024];
int len;
while(( len = reader.read( buf )) >= 0 ) {
sb.append( buf, 0, len );
}
}
return sb.toString();
}
}
}
import kotlin.concurrent.*
fun main( args: Array<String> ) {
val proc = Runtime.getRuntime().exec( arrayOf( "ls", "-l", "Process3.kt" , "Process3.txt" ))
val sbOut = StringBuilder()
val sbErr = StringBuilder()
val outThread = thread {
proc.inputStream.reader().use() {
sbOut.append( it.readText())
}
}
val errThread = thread {
proc.errorStream.reader().use() {
sbErr.append( it.readText())
}
}
proc.waitFor()
outThread.join()
errThread.join()
println( "stdout: " + sbOut )
println( "stderr: " + sbErr )
println( "exit code: " + proc.exitValue())
proc.destroy()
}
ProcessBuilder を使うことで、標準出力、エラー出力の出力先をファイルにすることができる。
fun main( args: Array<String> ) {
val pb = ProcessBuilder( "ls", "-l", "Process3.kt" , "Process3.txt" )
pb.redirectError( ProcessBuilder.Redirect.appendTo( File( "error.txt" )))
pb.redirectOutput( ProcessBuilder.Redirect.appendTo( File( "output.txt" )))
val proc = pb.start()
proc.waitFor()
println( "stdout: " + File( "output.txt" ).readText())
println( "stderr: " + File( "error.txt" ).readText() )
println( "exit code: " + proc.exitValue())
proc.destroy()
}
さらにエラー出力を標準出力にリダイレクトしてファイル出力することも可。
fun main( args: Array<String> ) {
val pb = ProcessBuilder( "ls", "-l", "Process3.kt" , "Process3.txt" )
pb.redirectErrorStream( true )
pb.redirectOutput( ProcessBuilder.Redirect.appendTo( File( "output.txt" )))
val proc = pb.start()
proc.waitFor()
println( "stdout + stderr: " + File( "output.txt" ).readText())
println( "exit code: " + proc.exitValue())
proc.destroy()
}