comp.lang.ada
 help / color / mirror / Atom feed
* How to run external program pipeline and capture output
@ 2019-10-28 17:24 Alain De Vos
  2019-10-29 10:31 ` joakimds
  0 siblings, 1 reply; 4+ messages in thread
From: Alain De Vos @ 2019-10-28 17:24 UTC (permalink / raw)


I like to run a command like :
/usr/local/bin/zsh -c "/bin/ls | /usr/bin/grep a"
But the procedure below produces no ouput, 

To make it strange, with /usr/local/bin/zsh -c "/bin/ls " it works fine.

procedure System_Command is
   Command    : String          := "/usr/local/bin/zsh -c ""/bin/ls | /usr/bin/grep a""";
   Args       : Argument_List_Access;
   Status     : aliased Integer;
   Separators : constant String := LF & CR;
   Reply_List : Slice_Set;
begin
   Ada.Text_IO.Put_Line (Command);
   Args := Argument_String_To_List (Command);
   -- execute the system command and get the output in a single string
   declare
      Response : String :=
        Get_Command_Output
          (Command   => Args (Args'First).all,
           Arguments => Args (Args'First + 1 .. Args'Last),
           Input     => "",
           Status    => Status'Access);
   begin
      Free (Args);
      -- split the output in a slice for easier manipulation
      if Status = 0 then
         Create (S          => Reply_List,
                 From       => Response,
                 Separators => Separators,
                 Mode       => Multiple);
      end if;
   end;
   -- do something with the system output. Just print it out
   for I in 1 .. Slice_Count (Reply_List) loop
      Put_Line (Slice (Reply_List, I));
   end loop;
end System_Command;


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How to run external program pipeline and capture output
  2019-10-28 17:24 How to run external program pipeline and capture output Alain De Vos
@ 2019-10-29 10:31 ` joakimds
  2019-10-29 16:47   ` Jeffrey R. Carter
  0 siblings, 1 reply; 4+ messages in thread
From: joakimds @ 2019-10-29 10:31 UTC (permalink / raw)


Den måndag 28 oktober 2019 kl. 18:24:41 UTC+1 skrev Alain De Vos:
> I like to run a command like :
> /usr/local/bin/zsh -c "/bin/ls | /usr/bin/grep a"
> But the procedure below produces no ouput, 
> 
> To make it strange, with /usr/local/bin/zsh -c "/bin/ls " it works fine.
> 
> procedure System_Command is
>    Command    : String          := "/usr/local/bin/zsh -c ""/bin/ls | /usr/bin/grep a""";
>    Args       : Argument_List_Access;
>    Status     : aliased Integer;
>    Separators : constant String := LF & CR;
>    Reply_List : Slice_Set;
> begin
>    Ada.Text_IO.Put_Line (Command);
>    Args := Argument_String_To_List (Command);
>    -- execute the system command and get the output in a single string
>    declare
>       Response : String :=
>         Get_Command_Output
>           (Command   => Args (Args'First).all,
>            Arguments => Args (Args'First + 1 .. Args'Last),
>            Input     => "",
>            Status    => Status'Access);
>    begin
>       Free (Args);
>       -- split the output in a slice for easier manipulation
>       if Status = 0 then
>          Create (S          => Reply_List,
>                  From       => Response,
>                  Separators => Separators,
>                  Mode       => Multiple);
>       end if;
>    end;
>    -- do something with the system output. Just print it out
>    for I in 1 .. Slice_Count (Reply_List) loop
>       Put_Line (Slice (Reply_List, I));
>    end loop;
> end System_Command;

In 2010 Gautier De Montmollin posted the following code snippet for executing terminal commands:

with Ada.Text_IO;                       use Ada.Text_IO;
with GNAT.OS_Lib;                       use GNAT.OS_Lib;
with GNAT.Expect;                       use GNAT.Expect;

procedure Pipe_test is
   Command : constant String := -- a command which should be long to
execute
      "gnatmake -f -Pbig_project.gpr";
   Pd      : Process_Descriptor;
   Args    : Argument_List_Access;
   Result  : Expect_Match;
begin
   Args := Argument_String_To_List (Command);
   Non_Blocking_Spawn
      (Pd,
       Command     => Args (Args'First).all,
       Args        => Args (Args'First + 1 .. Args'Last),
       Buffer_Size => 0);
   loop
      begin
         Expect (Pd, Result, Regexp => "\n", Timeout => 1_000);
         case Result is
            when Expect_Timeout =>
               Put("[timeout]"); -- no output for this time slice
            when Expect_Full_Buffer =>
               Put("[full]"); -- doesn't happen with buffer size = 0 ?
            when 1 =>
               Put(Expect_Out(Pd)); -- regexp matched
            when others =>
               Put("[?]"); -- shouldn't (and doesn't) happen
         end case;
      exception
         when Process_died => Put("[died]"); exit;
      end;
   end loop;
   Put(Expect_Out(Pd));
   Close (Pd);
end Pipe_test;

Best regards,
Joakim


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How to run external program pipeline and capture output
  2019-10-29 10:31 ` joakimds
@ 2019-10-29 16:47   ` Jeffrey R. Carter
  2019-10-30 13:41     ` Shark8
  0 siblings, 1 reply; 4+ messages in thread
From: Jeffrey R. Carter @ 2019-10-29 16:47 UTC (permalink / raw)


Den måndag 28 oktober 2019 kl. 18:24:41 UTC+1 skrev Alain De Vos:
> I like to run a command like :
> /usr/local/bin/zsh -c "/bin/ls | /usr/bin/grep a"
> But the procedure below produces no ouput,

My advice on this kind of thing is to do as much of it as possible in Ada. Since 
Ada.Directories lets you do "ls" kind of things, and you can select from the 
resulting file names using one of several regular-expression libraries if you 
like, I don't see any need to become non-portable.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How to run external program pipeline and capture output
  2019-10-29 16:47   ` Jeffrey R. Carter
@ 2019-10-30 13:41     ` Shark8
  0 siblings, 0 replies; 4+ messages in thread
From: Shark8 @ 2019-10-30 13:41 UTC (permalink / raw)


I agree with Mr. Carter -- the "Unix method" of pipes destroys data-consistency and forces ever more dependencies into the mix. Avoid going that route if at all possible, because it kills maintainability.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-30 13:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-28 17:24 How to run external program pipeline and capture output Alain De Vos
2019-10-29 10:31 ` joakimds
2019-10-29 16:47   ` Jeffrey R. Carter
2019-10-30 13:41     ` Shark8

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox