backtick and system command

M

mail4ashok

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
 
X

xhoster

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
 
M

mail4ashok

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
 
M

mail4ashok

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
 
J

Josef Moellers

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
 
M

mail4ashok

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
 
J

Josef Moellers

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";
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top