ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a program that generates a string of characters to the STDOUT.
I need to write a script to process that stream, the problem is that I don't get any input untill the character generating program quits..
Here is a program that generates characters:
#dtmfdecode | my_perl_script.pl
I tried using pipes, but perl script doesn't get any data unless dtmfdecode quits, but it is a real time process, where dtmfdecode will run in the background generating characters.
Thanx for the code... I guess I have a different case and it didn't solve the problem .
I think what I need is to echo a character when I press it. So if I run the script and press "A" it will print "A" right away without me pressing ENTER. Can this be done?
This way when I pipe the output of my #dtmfdecoder (character generator) I will be able to process characters.
I apologize if I am not being clear about my problem.
Let me try again. Here is what I need to do:
Say I would have a program #Stock_Update, that listens to some Network server and continuesly prints out stock updates to the screen without any spaces or new lines.
Example OUTPUT from #Stock_Update:
ABC$1232WAL$34DEL$56IBM$54 and so on.......
Now I need to write a Perl Script that will parse incoming real-time stream of data and produce report, showing largest stock, and average......
I tried piping #Stock_Update | my_perl_script.pl,
but since #Stock_Update never quits and doesn't print newlines I can't receive that data in a Perl Script.
I am sure if #Stock_Update would print out 1000 characters and then QUIT I would be able to take that input and process it, no big deal.
I also tried using FIFO or named Pipes but since #Stock_Update constantly writes to the FIFO it blocks Perl from reading it......
NOW in my case I am NOT using #Stock_Update, but #dtmfdecoder that takes SOUND CARD input and decodes DTMF tones and prints out characters to the screen. I need Perl to parse it just like in the fictional #Stock_Update......
Please Help!
I am sure someone tackled a similar problem. Do I need to use pipes or what?
Thank you!
The perl cookbook says to use a structure like this. You will have to invoke the stock program from the perl program that is reading its output though. Also, since the other program is piping data continuously, I guess you'd have undef the input record separator and grab each character as it comes. Then maybe sleep for a bit and try for more characters. It would be easier if the stock program had some kind of character to mark the end of a piece of data.
Code:
$pid = open $readme, "-|", "program", "arguments" or die "Couldn't fork: $!\n";
# no input record separator
undef $/;
MAIN:
while (1) {
while (<$readme>) {
# ...
}
# normally you'd close
#close $readme or die "Couldn't close: $!\n";
# take a nap
sleep 10;
}
use Term::ReadKey;
use strict;
$| = 1;
my $prog;
open ($prog, "./gen.pl |") or die "Couldn't fork: $!\n";
ReadMode 4, $prog;
my $key = '';
while($prog) {
$key = ReadKey(-1, $prog);
print $key;
}
ReadMode 0;
close $prog;
It prints Hello DudeHello DUDEHello DUDEHello DUDE over and over again, so it is good, problem solved partially !
Now the input for this program was ./gen.pl, which is another perl script that sleeps for 1 sec.
However if I use actual program open($prog, "./dtmfdecoder |") or die "Couldn't fork: $! \n";
the program seems to constantly block the pipe since it always writes to STDOUT and I still get nothing.....
This is beginning to bother me, but I am not giving up. I am sure there is a way to do it in Perl.
Wow it is finally working... it wasn't writting to STDERR, but thanx for the tip I'll keep that in mind next time..
The reason it didn't work was because the program that I have #dtmfdecode ocassionally starts and doesn't decode as
if it can't open a sound card or something, there are no error messages so it was really hard to debug.
So the problem was not with the script, but with the #dtmfdecode that sometimes fails to initialize properly, I'll have to look into that, but it works.
Perl can process a real-time character stream
I was also able to solve this problem by running #dtmfdecode > .buff on a seperate terminal
and then doing sysread(), like this
open (README, ".buff") or die "Couldn't open file: $!\n";
while(1) {
$|=1;
if( sysread(README, $key, 1))
{
print $key;
}
}
Thanx!
P.S. I also have a program #dtmfencode, I use it from the script using exec 'dtmfencode';
But script quits when the program is done, how can I go back to the script??? Should I fork instead of exec 'dtmfencode';
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.