backtick and system command

Discussion in 'Perl Misc' started by mail4ashok@gmail.com, Jan 14, 2007.

  1. Guest

    Hi

    I am trying to capture output from another script(Tcl) with in a Perl
    script. I read the FAQ's and usenet post's before I posted.

    My requirements are
    1. Capture output from external script
    2. Write the output on STDOUT
    3. The output should be unbuffered( basically show output
    synchronously)

    I can capture and print to STDOUT using
    print ($a=`script`);
    but the o/p gets buffered. Setting $| has no effect.

    I can use Perl system function to redirect but I loose terminal output.

    Sorry, If a method is explained in FAQ, it's possible that I did not
    understand.

    Any example to do this is appreciated.

    Thanks
     
    , Jan 14, 2007
    #1
    1. Advertising

  2. Guest

    wrote:
    > Hi
    >
    > I am trying to capture output from another script(Tcl) with in a Perl
    > script. I read the FAQ's and usenet post's before I posted.
    >
    > My requirements are
    > 1. Capture output from external script
    > 2. Write the output on STDOUT
    > 3. The output should be unbuffered( basically show output
    > synchronously)
    >
    > I can capture and print to STDOUT using
    > print ($a=`script`);
    > but the o/p gets buffered. Setting $| has no effect.
    >
    > I can use Perl system function to redirect but I loose terminal output.


    How about just using the system function with no redirect? The subprocess
    should inherit and perl's STDOUT and print to it automatically.

    Or you could open a pipe to the command:

    open my $fh, "some command |" or die $!;
    while (<$fh>) {
    print $_;
    push @store, $_;
    };

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jan 14, 2007
    #2
    1. Advertising

  3. Guest

    Thanks


    > How about just using the system function with no redirect? The subprocess
    > should inherit and perl's STDOUT and print to it automatically.



    But can you capture the o/p to a var at the same time ?

    > Or you could open a pipe to the command:
    >
    > open my $fh, "some command |" or die $!;
    > while (<$fh>) {
    > print $_;
    > push @store, $_;
    > };


    I havn't tried this, but I will give that a try. Does method wait for
    the command to complete
    before displaying then it wouldn't meet my req to have synchronous
    o/p.

    I was also thinking about piping using tee, but that disturbs my $?
    (return status from the command that I am intreted in )

    Thanks
     
    , Jan 14, 2007
    #3
  4. Guest

    replyin to my own post - did not intent to break any rules

    this seem to work; may not be efficient and maybe longwinded

    system "{ command ; echo $? >/tmp/rc; } | tee /tmp/t";

    thanks everyone
     
    , Jan 15, 2007
    #4
  5. wrote:
    > Hi
    >
    > I am trying to capture output from another script(Tcl) with in a Perl
    > script. I read the FAQ's and usenet post's before I posted.
    >
    > My requirements are
    > 1. Capture output from external script
    > 2. Write the output on STDOUT
    > 3. The output should be unbuffered( basically show output
    > synchronously)
    >
    > I can capture and print to STDOUT using
    > print ($a=`script`);
    > but the o/p gets buffered. Setting $| has no effect.
    >
    > I can use Perl system function to redirect but I loose terminal output.
    >
    > Sorry, If a method is explained in FAQ, it's possible that I did not
    > understand.
    >
    > Any example to do this is appreciated.


    It's not the Perl script's fault that the Tcl interpreter buffers its
    output.
    There is little you can do in your Perl script to correct that.

    I almost wrote "nothing you can do" as there is a solution:
    do not run your Tcl script through a pipe but rather set up a pseudo-tty
    between the Perl and the Tcl script. That way the Tcl script will assume
    a terminal on its stdout (which, in effect, it has) and will send
    line-buffered output.

    Expect (a Tcl based software) does that.

    Josef
    --
    Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize
    -- T. Pratchett
     
    Josef Moellers, Jan 15, 2007
    #5
  6. Guest

    > It's not the Perl script's fault that the Tcl interpreter buffers its
    > output.
    > There is little you can do in your Perl script to correct that.


    that is not true.

    #!/usr/bin/perl -w
    select STDOUT;
    $|=1;
    print `echo test;sleep 5;echo test`;
    __END__

    o/p:
    time goes by 5 seconds
    test
    test

    #!/usr/bin/perl -w
    select STDOUT;
    $|=1;
    print system "echo test;sleep 5;echo test";
    __END__

    o/p:
    test
    time goes by 5 seconds
    test

    > I almost wrote "nothing you can do" as there is a solution:
    > do not run your Tcl script through a pipe but rather set up a pseudo-tty
    > between the Perl and the Tcl script. That way the Tcl script will assume
    > a terminal on its stdout (which, in effect, it has) and will send
    > line-buffered output.
    >
    > Expect (a Tcl based software) does that.


    Actually I wasn't doing fully disclosing all the details, the script
    called by Perl is a Expect script
    most of it Tcl. I think I am correct in saying that the "puts" Tcl
    function is unbuffered.

    So what I experienced is a difference between backtick and system
    command. Anyway, I used a work around as mentioned in my last post.

    Thanks for your reply
     
    , Jan 15, 2007
    #6
  7. J. Gleixner Guest

    wrote:

    > Actually I wasn't doing fully disclosing all the details, the script
    > called by Perl is a Expect script
    > most of it Tcl. I think I am correct in saying that the "puts" Tcl
    > function is unbuffered.


    There's an Expect module, you could use, instead of an external Tcl
    script: http://search.cpan.org/~rgiersig/Expect-1.20/Expect.pod
     
    J. Gleixner, Jan 15, 2007
    #7
  8. wrote:
    >>It's not the Perl script's fault that the Tcl interpreter buffers its
    >>output.
    >>There is little you can do in your Perl script to correct that.

    >
    >
    > that is not true.
    >
    > #!/usr/bin/perl -w
    > select STDOUT;
    > $|=1;
    > print `echo test;sleep 5;echo test`;
    > __END__
    >
    > o/p:
    > time goes by 5 seconds
    > test
    > test


    > #!/usr/bin/perl -w
    > select STDOUT;
    > $|=1;
    > print system "echo test;sleep 5;echo test";
    > __END__
    >
    > o/p:
    > test
    > time goes by 5 seconds
    > test
    >


    Note that a "0" is also printed, but you don't show it:

    josef@bounty:~> perl
    print system "echo test;sleep 5;echo test";
    test
    test
    0josef@bounty:~>
    ^

    The difference between the two examples is that the return value of the
    back-quoted command sequence is the output of the command sequence while
    the return value of the "system" command is the exit status of the
    executed command (a shell, in this case as the string contains shell
    meta characters).
    I.e. in the first case, "print" prints the two "test"s while in the
    second case, the two "echo"s print the "test"s.

    Try

    my $x = `echo Test1`;
    my $y = system("echo Test2");

    See?

    If not, add

    print "x=$x\ny=$y\n";

    >>I almost wrote "nothing you can do" as there is a solution:
    >>do not run your Tcl script through a pipe but rather set up a pseudo-tty
    >>between the Perl and the Tcl script. That way the Tcl script will assume
    >>a terminal on its stdout (which, in effect, it has) and will send
    >>line-buffered output.
    >>
    >>Expect (a Tcl based software) does that.

    >
    >
    > Actually I wasn't doing fully disclosing all the details, the script
    > called by Perl is a Expect script
    > most of it Tcl. I think I am correct in saying that the "puts" Tcl
    > function is unbuffered.


    It appears I'm wrong in assuming that Tcl's output is buffered: it's not:

    test.tcl:
    puts "line1"
    exec /bin/sleep 10
    puts "line2"

    test.pl:
    open(my $tcl, 'tclsh test.tcl|');
    select STDOUT; $|=1;
    while (<$tcl>) {
    print;
    }

    prints the two lines with a 10s delay in between.

    > So what I experienced is a difference between backtick and system
    > command.


    The work differently. Therefore there is a difference.

    --
    Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize
    -- T. Pratchett
     
    Josef Moellers, Jan 16, 2007
    #8
    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. Leszek Dubiel
    Replies:
    3
    Views:
    9,831
  2. John Carter
    Replies:
    18
    Views:
    257
    Robert Klemme
    Aug 13, 2008
  3. Martin Kissner
    Replies:
    16
    Views:
    176
    Dr.Ruud
    Nov 20, 2005
  4. Replies:
    8
    Views:
    613
  5. Replies:
    5
    Views:
    408
    Willem
    Dec 5, 2012
Loading...

Share This Page