Newbie: How do I filter output to the screen and writing the orginal output to a file?

Discussion in 'Perl Misc' started by Mav, Jul 2, 2004.

  1. Mav

    Mav Guest

    Hi, all


    I need to write a perl script that execute (using system) command
    to do build.

    While it is doing the build, I would like to print out the item is
    build on the screen,
    the orginal build output will go to the a log file (build.log).


    @args = ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");

    open (OLDSTDOUT, ">&STDOUT") or die "Couldn't dup STDOUT: $!";
    open(STDOUT, "> build.log") || die "Can't redirect stdout";

    #once this execute it starts writing to build.log
    $buildResult = system(@args);

    #The following write to build.log
    #--Build Item A
    #compiling a1.cpp
    #compiling a2.cpp
    ....
    #--Build Item B
    #compiling b1.cpp
    #compiling b2.cpp
    ....

    At the same time, how do I only print the following on the screen?
    #To screen
    Build Item A
    Build Item B

    Do I need to start a another process in order to do it?
    How do I filter the STDOUT(to file) at the same time output to screen?


    Thanks,
    Mav
     
    Mav, Jul 2, 2004
    #1
    1. Advertising

  2. Mav

    John Bokma Guest

    Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Mav wrote:

    > Hi, all
    >
    >
    > I need to write a perl script that execute (using system) command
    > to do build.
    >
    > While it is doing the build, I would like to print out the item is
    > build on the screen,
    > the orginal build output will go to the a log file (build.log).
    >
    >
    > @args = ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    >
    > open (OLDSTDOUT, ">&STDOUT") or die "Couldn't dup STDOUT: $!";
    > open(STDOUT, "> build.log") || die "Can't redirect stdout";


    use or or || this is confusing.

    > #once this execute it starts writing to build.log
    > $buildResult = system(@args);


    use strict;
    use warnings;

    > #The following write to build.log
    > #--Build Item A
    > #compiling a1.cpp
    > #compiling a2.cpp
    > ...
    > #--Build Item B
    > #compiling b1.cpp
    > #compiling b2.cpp
    > ...
    >
    > At the same time, how do I only print the following on the screen?
    > #To screen
    > Build Item A
    > Build Item B
    >
    > Do I need to start a another process in order to do it?
    > How do I filter the STDOUT(to file) at the same time output to screen?


    use a pipe instead of system

    --
    John MexIT: http://johnbokma.com/mexit/
    personal page: http://johnbokma.com/
    Experienced Perl programmer available: http://castleamber.com/
    Happy Customers: http://castleamber.com/testimonials.html
     
    John Bokma, Jul 2, 2004
    #2
    1. Advertising

  3. Mav

    Mav Guest

    I need to execute (using system(@args)) in order to get the output.
    Would you give me an example? I read the perl section but still don't
    quite understand how to make it work for my case.

    Any comments or input are welcome.

    TIA,
    Mav



    John Bokma <> wrote in message news:<40e5dd99$0$189$>...
    > Mav wrote:
    >
    > > Hi, all
    > >
    > >
    > > I need to write a perl script that execute (using system) command
    > > to do build.
    > >
    > > While it is doing the build, I would like to print out the item is
    > > build on the screen,
    > > the orginal build output will go to the a log file (build.log).
    > >
    > >
    > > @args = ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    > >
    > > open (OLDSTDOUT, ">&STDOUT") or die "Couldn't dup STDOUT: $!";
    > > open(STDOUT, "> build.log") || die "Can't redirect stdout";

    >
    > use or or || this is confusing.
    >
    > > #once this execute it starts writing to build.log
    > > $buildResult = system(@args);

    >
    > use strict;
    > use warnings;
    >
    > > #The following write to build.log
    > > #--Build Item A
    > > #compiling a1.cpp
    > > #compiling a2.cpp
    > > ...
    > > #--Build Item B
    > > #compiling b1.cpp
    > > #compiling b2.cpp
    > > ...
    > >
    > > At the same time, how do I only print the following on the screen?
    > > #To screen
    > > Build Item A
    > > Build Item B
    > >
    > > Do I need to start a another process in order to do it?
    > > How do I filter the STDOUT(to file) at the same time output to screen?

    >
    > use a pipe instead of system
     
    Mav, Jul 3, 2004
    #3
  4. Mav

    Mav Guest

    I need to execute (using the system (@args)) in order to get the
    output.
    Would you give me an example?
    I read the perl section for pipe, still don't quite understand how to
    make my code work.
    Any input or comments are welcome,

    TIA,
    Mav


    John Bokma <> wrote in message news:<40e5dd99$0$189
    $>...
    > Mav wrote:
    >
    > > Hi, all
    > >
    > >
    > > I need to write a perl script that execute (using system) command
    > > to do build.
    > >
    > > While it is doing the build, I would like to print out the item is
    > > build on the screen,
    > > the orginal build output will go to the a log file (build.log).
    > >
    > >
    > > @args = ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    > >
    > > open (OLDSTDOUT, ">&STDOUT") or die "Couldn't dup STDOUT: $!";
    > > open(STDOUT, "> build.log") || die "Can't redirect stdout";

    >
    > use or or || this is confusing.
    >
    > > #once this execute it starts writing to build.log
    > > $buildResult = system(@args);

    >
    > use strict;
    > use warnings;
    >
    > > #The following write to build.log
    > > #--Build Item A
    > > #compiling a1.cpp
    > > #compiling a2.cpp
    > > ...
    > > #--Build Item B
    > > #compiling b1.cpp
    > > #compiling b2.cpp
    > > ...
    > >
    > > At the same time, how do I only print the following on the screen?
    > > #To screen
    > > Build Item A
    > > Build Item B
    > >
    > > Do I need to start a another process in order to do it?
    > > How do I filter the STDOUT(to file) at the same time output to screen?

    >
    > use a pipe instead of system
     
    Mav, Jul 3, 2004
    #4
  5. Mav <> wrote:

    > I need to execute (using system(@args)) in order to get the output.



    system() does not give you the output!

    You need something else ("perldoc -f system" may suggest what "else" is).


    [ snip 50 lines of upside-down full-quote.
    Please do not do that.
    ]

    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jul 3, 2004
    #5
  6. Mav

    Joe Smith Guest

    Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Mav wrote:

    > At the same time, how do I only print the following on the screen?
    > #To screen
    > Build Item A
    > Build Item B
    > How do I filter the STDOUT(to file) at the same time output to screen?


    print OLDSTDOUT "Build Item A\n";
    system(@args_A);
    print OLDSTDOUT "Build Item B\n";
    system(@args_B);

    -Joe
     
    Joe Smith, Jul 3, 2004
    #6
  7. Mav

    Mav Guest

    Yes, system(@args) on my case will give me the build output on the
    screen.
    'coz the args I parse in is execute an application that will print all
    the step on the screen.

    However, I want to print out only certain pattern on the screen, at
    the same time got the orginal output into the log file. (If you look
    at my orginal post).

    Regards,
    Mav


    Tad McClellan <> wrote in message news:<>...
    > Mav <> wrote:
    >
    > > I need to execute (using system(@args)) in order to get the output.

    >
    >
    > system() does not give you the output!
    >
    > You need something else ("perldoc -f system" may suggest what "else" is).
    >
    >
    > [ snip 50 lines of upside-down full-quote.
    > Please do not do that.
    > ]
     
    Mav, Jul 3, 2004
    #7
  8. Mav wrote:
    > Yes, system(@args) on my case will give me the build output on the
    > screen.
    > 'coz the args I parse in is execute an application that will print all
    > the step on the screen.


    And exactly that is the problem. system() doesn't capture the output. This
    means
    - your application still prints to the terminal
    - your Perl program never recieves the output, doesn't know about it, can't
    process it, can't filter it, can't do anything with it.

    > However, I want to print out only certain pattern on the screen, at
    > the same time got the orginal output into the log file. (If you look
    > at my orginal post).


    Then --as other have suggested already-- use a different method to call the
    external application. A method that allows your Perl program to capture and
    process the output as needed.

    jue
     
    Jürgen Exner, Jul 3, 2004
    #8
  9. Mav

    Daedalus Guest

    > And exactly that is the problem. system() doesn't capture the output. This
    > means


    OReilly's Learning Perl (3rd Ed)
    "The system function:
    ....The child process inherits Perl's standard input, standard output, and
    standard error..."

    There must be something I'm missing.
     
    Daedalus, Jul 3, 2004
    #9
  10. Daedalus wrote:
    >> And exactly that is the problem. system() doesn't capture the
    >> output. This means

    >
    > OReilly's Learning Perl (3rd Ed)
    > "The system function:
    > ...The child process inherits Perl's standard input, standard output,
    > and standard error..."
    >
    > There must be something I'm missing.


    Maybe you are missing the meaning of "inherits".
    If e.g. the file descriptor STDOUT in the Perl program is linked to a file
    "foobar", then the child process will inherit this connection, i.e. in the
    child process STDOUT will be linked to "foobar", too.

    jue
     
    Jürgen Exner, Jul 3, 2004
    #10
  11. Mav

    Daedalus Guest

    > >> And exactly that is the problem. system() doesn't capture the
    > >> output. This means

    > >
    > > OReilly's Learning Perl (3rd Ed)
    > > "The system function:
    > > ...The child process inherits Perl's standard input, standard output,
    > > and standard error..."
    > >
    > > There must be something I'm missing.

    >
    > Maybe you are missing the meaning of "inherits".
    > If e.g. the file descriptor STDOUT in the Perl program is linked to a file
    > "foobar", then the child process will inherit this connection, i.e. in the
    > child process STDOUT will be linked to "foobar", too.


    Ok I think I got it. Is this would be a good way to capture the child
    process output into perl ?

    open PROCRETURN, "@ARGV|"

    or maybe

    @procreturn = `@ARGV`


    Thanks
    DAE
     
    Daedalus, Jul 3, 2004
    #11
  12. Mav

    Mav Guest

    First of all, I thank for so many people reply my post. However, I
    still didn't get my progam working. I think it is because I didn't
    explain it correctly.
    I will try on this mail:

    On my perl script, I would like to execute the command:
    @args = ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    This is an Vs.net command that allow user to build the solution(my
    solution) from the console. Once this command got execute, the output
    will print on the SCREEN like:
    --Build Item A
    compiling a1.cpp
    compiling a2.cpp
    compiling a3.cpp

    ...
    --Build Item B
    compiling b1.cpp
    compiling b2.cpp
    compiling b3.cpp
    ...
    --Build Item C
    compiling c1.cpp
    ...
    However, I don't want all the detail got print on the screen, I want
    only key main being print on the SCREEN like,:

    --Build Item A
    --Build Item B
    --Build Item C

    But still keep the orignal format in the a log FILE (build.log) which
    will contians the
    --Build Item A
    compiling a1.cpp
    compiling a2.cpp
    compiling a3.cpp

    ...
    --Build Item B
    compiling b1.cpp
    compiling b2.cpp
    compiling b3.cpp
    ...
    --Build Item C
    compiling c1.cpp
    ...

    Is that possible to do?

    Thanks,
    Mav
     
    Mav, Jul 4, 2004
    #12
  13. Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Mav wrote:
    > I still didn't get my progam working. I think it is because I
    > didn't explain it correctly.


    Or you did not listen to the advices you got. ;-)

    > On my perl script, I would like to execute the command:
    > @args =
    > ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    > This is an Vs.net command that allow user to build the solution(my
    > solution) from the console. Once this command got execute, the
    > output will print on the SCREEN like:
    > --Build Item A
    > compiling a1.cpp
    > compiling a2.cpp
    > compiling a3.cpp


    <snip>

    > However, I don't want all the detail got print on the screen, I
    > want only key main being print on the SCREEN like,:
    >
    > --Build Item A
    > --Build Item B
    > --Build Item C
    >
    > But still keep the orignal format in the a log FILE (build.log)


    You may want to try something like this:

    my $output = qx(@args);
    open LOG, '>> build.log' or die $!;
    print LOG $output;
    close LOG;
    print "$1\n" while $output =~ /^(\s*--.+)/gm;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 4, 2004
    #13
  14. Mav

    Mav Guest

    Thanks, only after the build completed
    it print out the info. I would like to show up what is building...=(
    It will print "Start" and nothing show up...
    Do I need to create a seperate process?

    #Here is the completed code.
    #!/usr/bin/perl

    $build_config = Release;

    # Setup the path to devenv
    my $devPath = $ENV{VS71COMNTOOLS};
    $devPath =~ s/\\\w+\\$//;
    $devPath =~ s/$/\\IDE\\/;

    # Do the build
    if (-e "b.log") {
    @args = ("del b.log");
    system(@args);
    }

    @args = ("\"$devPath\\devenv.com\" ..\\Solution\\my.sln /build $build_config");

    print "Start\n";
    my $output = qx(@args);

    open LOG, '>> b.log' or die $!;
    print LOG $output;
    close LOG;
    print "$1\n" while $output =~ /^(\s*--.+)/gm;



    Gunnar Hjalmarsson <> wrote in message news:<>...
    > Mav wrote:
    > > I still didn't get my progam working. I think it is because I
    > > didn't explain it correctly.

    >
    > Or you did not listen to the advices you got. ;-)
    >
    > > On my perl script, I would like to execute the command:
    > > @args =
    > > ("\"$devPath\\devenv.com\" Solution\\my.sln /build Release");
    > > This is an Vs.net command that allow user to build the solution(my
    > > solution) from the console. Once this command got execute, the
    > > output will print on the SCREEN like:
    > > --Build Item A
    > > compiling a1.cpp
    > > compiling a2.cpp
    > > compiling a3.cpp

    >
    > <snip>
    >
    > > However, I don't want all the detail got print on the screen, I
    > > want only key main being print on the SCREEN like,:
    > >
    > > --Build Item A
    > > --Build Item B
    > > --Build Item C
    > >
    > > But still keep the orignal format in the a log FILE (build.log)

    >
    > You may want to try something like this:
    >
    > my $output = qx(@args);
    > open LOG, '>> build.log' or die $!;
    > print LOG $output;
    > close LOG;
    > print "$1\n" while $output =~ /^(\s*--.+)/gm;
     
    Mav, Jul 6, 2004
    #14
  15. Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Mav wrote:
    > Gunnar Hjalmarsson wrote:
    >> You may want to try something like this:
    >>
    >> my $output = qx(@args);
    >> open LOG, '>> build.log' or die $!;
    >> print LOG $output;
    >> close LOG;
    >> print "$1\n" while $output =~ /^(\s*--.+)/gm;

    >
    > Thanks, only after the build completed it print out the info. I
    > would like to show up what is building...=(


    Well, I realize that, but it's beyond the scope of my answer. :) Just
    wanted to say (like several others have done) that you should not
    necessarily use the system() function.

    I don't know the complete answer to your question.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 6, 2004
    #15
  16. Mav

    Anno Siegel Guest

    Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > Mav wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> You may want to try something like this:
    > >>
    > >> my $output = qx(@args);
    > >> open LOG, '>> build.log' or die $!;
    > >> print LOG $output;
    > >> close LOG;
    > >> print "$1\n" while $output =~ /^(\s*--.+)/gm;

    > >
    > > Thanks, only after the build completed it print out the info. I
    > > would like to show up what is building...=(

    >
    > Well, I realize that, but it's beyond the scope of my answer. :) Just
    > wanted to say (like several others have done) that you should not
    > necessarily use the system() function.
    >
    > I don't know the complete answer to your question.


    Backticks and qx wait until the background process is finished and
    deliver all the output at once. To see the lines of output as they
    appear, open a filehandle to capture the output. Untested:

    open my $proc, "@args |";
    /^(\s*--.+)/ and print "$1\n" while <$proc>;

    Anno
     
    Anno Siegel, Jul 7, 2004
    #16
  17. Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Anno Siegel wrote:
    > Backticks and qx wait until the background process is finished and
    > deliver all the output at once. To see the lines of output as they
    > appear, open a filehandle to capture the output. Untested:
    >
    > open my $proc, "@args |";
    > /^(\s*--.+)/ and print "$1\n" while <$proc>;


    Thanks, Anno!

    So, then a solution to the OP's question may be:

    open my $log, '>> build.log' or die $!;
    open my $proc, "@args |" or die $!;
    while (<$proc>) {
    print $log $_;
    print if /^(\s*--.+)/;
    }
    close $proc;
    close $log;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 7, 2004
    #17
  18. Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Gunnar Hjalmarsson wrote:
    >
    > print if /^(\s*--.+)/;


    That can obviously be shortened to:

    print if /^\s*--/;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 7, 2004
    #18
  19. Mav

    Mav Guest

    Re: Newbie: How do I filter output to the screen and writing the orginal output to a file?

    Thanks Gunnar. That is exactly the answer I am looking for.
    If I use system(@args) I can get a $buildResult from it.
    $buildResult = system(@args); (That will give me return 0 if build successful).

    Now, if I am using open:
    open my $proc, "@args |" or die $!;
    Is that anyway I can get the $buildResult?

    Thanks,
    Mav


    Gunnar Hjalmarsson <> wrote in message news:<>...
    > Anno Siegel wrote:
    > > Backticks and qx wait until the background process is finished and
    > > deliver all the output at once. To see the lines of output as they
    > > appear, open a filehandle to capture the output. Untested:
    > >
    > > open my $proc, "@args |";
    > > /^(\s*--.+)/ and print "$1\n" while <$proc>;

    >
    > Thanks, Anno!
    >
    > So, then a solution to the OP's question may be:
    >
    > open my $log, '>> build.log' or die $!;
    > open my $proc, "@args |" or die $!;
    > while (<$proc>) {
    > print $log $_;
    > print if /^(\s*--.+)/;
    > }
    > close $proc;
    > close $log;
     
    Mav, Jul 7, 2004
    #19
  20. Re: Newbie: How do I filter output to the screen and writing theorginal output to a file?

    Mav wrote:
    > Thanks Gunnar. That is exactly the answer I am looking for.


    Good, but don't forget to thank Anno who provided the actual solution...

    > If I use system(@args) I can get a $buildResult from it.
    > $buildResult = system(@args); (That will give me return 0 if build
    > successful).
    >
    > Now, if I am using open:
    > open my $proc, "@args |" or die $!;
    > Is that anyway I can get the $buildResult?


    You can check the return value from close():

    close $proc or die "Build failed $! $?";

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 7, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. HNguyen
    Replies:
    4
    Views:
    2,410
    HNguyen
    Dec 21, 2004
  2. chuck amadi
    Replies:
    1
    Views:
    492
    Larry Bates
    Jun 23, 2004
  3. zax75
    Replies:
    1
    Views:
    1,105
  4. Biranchi Narayan Panda
    Replies:
    1
    Views:
    2,753
    Alexey Smirnov
    Feb 17, 2010
  5. drew
    Replies:
    6
    Views:
    176
Loading...

Share This Page