in reply to Perl Cascading Calls, Losing STDIN?
Given the code:
for (1..3) { print "$_: "; system(qw( perl -wle ), "print scalar <STDIN>"); }
You will have some luck reading from a terminal, i.e. the keyboard. Each script will read as much as it can, which happens to (usually) be a single line, because that's what the user types. If you read from a file or a pipe you will more than likely encounter problems. The reason is buffering; each program reads more than it needs (some buffer size, probably 1024 bytes), in order to find the newline. One program reads 1024 bytes, buffers what it didn't use for later, and exits; any subsequent programs start at 1024 bytes in, and nothing is there, so they read EOF.
Why a C shell program works doing this is a mystery; perhaps they aren't using buffered calls and are reading a character at a time until they get a newline. Something like this:
for (1..3) { print "$_: "; system( qw( perl -we ), q{ while (1) { my $bytes = sysread(STDIN, my $c, 1); last if $bytes <= 0 || $c eq "\n"; print $c; } } ); print "\n"; }
Notice this is going to be terribly slow on any sizeable input; for every character there is at least one syscall. Frankly, relying on all of the programs in a chain to read from the same filehandle is flakey and of poor design; not only do you have issues with buffering, you're relying on an implicit interface, rather than explicitly passing around what you need. You should be calling each program with the arguments it needs, or handing it the input you want from the previous program in the chain.
For example, use a piped open (see perlipc) or IPC::Open2 to open pipes to and/or from each program, and print to them as necessary. POE may be a help, in that it allows you to spawn processes simultaneously and monitor them. It's hard to say, you didn't mention why your system is designed this way, but it sounds to me like it would benefit greatly from a redesign.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Perl Cascading Calls, Losing STDIN?
by cainlord (Initiate) on Jun 15, 2004 at 14:26 UTC | |
by cainlord (Initiate) on Jun 15, 2004 at 14:31 UTC |