[Lazarus] Run 3 extrenal program, pipeline

xmldom at seznam.cz xmldom at seznam.cz
Thu Feb 2 12:00:52 CET 2012


Hi, I need run 3 external program and redirected output: first | second | third

For example: 
   df -hT | grep -v -E 'tmpfs|ecryptfs' | grep 'sda2'
it gives
   /dev/sda2     ext4     19G   11G  7,6G  58% /

I use this http://wiki.lazarus.freepascal.org/Executing_External_Programs#How_to_redirect_output_with_TProcess sample code. It works fine for  first | second.

For three programs I try edit it:


function threePipe(inputA, inputB, inputC: string): string;
var
 FirstProcess, SecondProcess, ThirdProcess: TProcess;
 Buffer: array[0..127] of char;
 ReadCount: Integer;
 ReadSize: Integer;
begin
 FirstProcess  := TProcess.Create(nil);
 SecondProcess := TProcess.Create(nil);
 ThirdProcess := TProcess.Create(nil);

 FirstProcess.Options  := [poUsePipes];
 SecondProcess.Options := [poUsePipes];
 ThirdProcess.Options  := [poUsePipes,poStderrToOutPut];

 FirstProcess.CommandLine  := inputA;
 SecondProcess.CommandLine := inputB;
 ThirdProcess.CommandLine := inputC;

 FirstProcess.Execute;
 SecondProcess.Execute;
 ThirdProcess.Execute;

 while FirstProcess.Running or (FirstProcess.Output.NumBytesAvailable > 0) do
 begin
   if FirstProcess.Output.NumBytesAvailable > 0 then
   begin
     ReadSize := FirstProcess.Output.NumBytesAvailable;
     if ReadSize > SizeOf(Buffer) then
       ReadSize := SizeOf(Buffer);
     ReadCount := FirstProcess.Output.Read(Buffer[0], ReadSize);
     SecondProcess.Input.Write(Buffer[0], ReadCount);
   end;
 end;
 SecondProcess.CloseInput;

 while SecondProcess.Running or (SecondProcess.Output.NumBytesAvailable > 0) do
 begin
   if SecondProcess.Output.NumBytesAvailable > 0 then
   begin
     ReadSize := SecondProcess.Output.NumBytesAvailable;
     if ReadSize > SizeOf(Buffer) then
       ReadSize := SizeOf(Buffer);
     ReadCount := SecondProcess.Output.Read(Buffer[0], ReadSize);
     ThirdProcess.Input.Write(Buffer[0], ReadCount);
   end;
 end;
 ThirdProcess.CloseInput;


 while ThirdProcess.Running do
   Sleep(1);
 ReadSize := ThirdProcess.Output.NumBytesAvailable;
 if ReadSize > SizeOf(Buffer) then
   ReadSize := SizeOf(Buffer);
 if ReadSize > 0 then
 begin
   ReadCount := ThirdProcess.Output.Read(Buffer, ReadSize);
   //WriteLn(Copy(Buffer,0, ReadCount));
 end
 else
   WriteLn('grep did not find what we searched for. ', ThirdProcess.ExitStatus);

 FirstProcess.Free;
 SecondProcess.Free;
 ThirdProcess.Free;
 threePipe := Copy(Buffer,0, ReadCount);
end;



But after i call 
   Label1.Caption:=threePipe('df -hT', 'grep -v -E ''tmpfs|ecryptfs''', 'grep ''sda2''');
function my application end with infinite loop.

Where I do an error?




More information about the Lazarus mailing list