you could theoretically do this with exec()
if you redirected output and then read the output from a file, but coordinating with the process would be nearly impossible without first finding its PID. This is what proc_open()
is for. popen()
might work, but I'm guessing the progress bar is written to stderr
, and that is what I mocked up for you here.
Here's a little program that should be a working example for you:
<?php
$descriptors = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open( "/usr/bin/env ruby ./rlike.rb 1 10", $descriptors, $pipes, getcwd() );
if( is_resource($process) ){
echo "ran process\n";
do{
$status = proc_get_status($process);
if(! $status["running"]) break;
fflush($pipes[2]);
$progressbar = fread( $pipes[2],1 );
if( $progressbar == "\r" ) echo "\n";
else echo "$progressbar";
}while( $status["running"] );
fclose($pipes[0]);
fclose($pipes[2]);
echo "\nProcess complete. \n";
print_r( $status );
}else{
echo "Failed to run process.\n";
}
The output looks like this:
ran process
|> | 00%
|==> | 10%
|====> | 20%
|======> | 30%
|========> | 40%
|==========> | 50%
|============> | 60%
|==============> | 70%
|================> | 80%
|==================> | 90%
|====================>| 100%
Process complete.
Array
(
[command] => /usr/bin/env ruby ./rlike.rb 1 10
[pid] => 60306
[running] =>
[signaled] =>
[stopped] =>
[exitcode] => 0
[termsig] => 0
[stopsig] => 0
)
Finally, the ruby program that writes out a progress bar looks as follows ( behold, the awesomeness of ruby syntax :) ):
wait = ARGV[1].to_f || 10.0
repeat = ARGV[2].to_i
repeat = 10 if !repeat or repeat == 0
wait = 1 if !wait or wait == 0
barlen = 20
(repeat+1).times do |t|
curlen = ( repeat == 0 ? 0 : ( t*barlen/repeat ) )
bar = ( "%#{curlen}s>" % "" ).gsub( " ", "=")
$stderr.print sprintf("\r|%- #{barlen+1}s| %3.2d%% ", bar, 100*t/repeat )
$stderr.flush
sleep 1 unless t == repeat
end
From that example, you should be able to get anything you like working. Word of warning: I'm rewriting the entire progress bar each time and returning to the beginning of the line with \r
- but depending on how the Rscript progress bar works, this may not be the case.