al@ee.pitt.edu (Alan Martello) (07/17/90)
I give up. I want to pipe binary data from one program to another
while (possibly) filtering it.
Why doesn't this work and how can it be modified to work?
------------------------------------------------------------------------
---------
#!/bin/perl -P
#
# this works (of course) since the shell does the pipe
#
system("cat /vmunix | dd of=./vmunix_copy1");
#
# how can I make perl do the same thing explicitly ?
# THIS DOESN'T WORK
#
open(TMPFH,"cat /vmunix | ");
open(OUTFH, "| dd of=./vmunix_copy2");
while(<TMPFH>)
{
printf OUTFH $line;
read(TMPFH, $line, $length);
}
close(OUTFH);
close(TMPFH);
------------------------------------------------------------------------
---------
*******************************************************************
Alan R. Martello Electrical Engineering Dept.
al@ee.pitt.edu University of Pittsburgh
*******************************************************************
merlyn@iwarp.intel.com (Randal Schwartz) (07/18/90)
In article <8120@pitt.UUCP>, al@ee (Alan Martello) writes: | I give up. I want to pipe binary data from one program to another | while (possibly) filtering it. | | Why doesn't this work and how can it be modified to work? | | ------------------------------------------------------------------------ | open(TMPFH,"cat /vmunix | "); | open(OUTFH, "| dd of=./vmunix_copy2"); | | while(<TMPFH>) | { | printf OUTFH $line; | read(TMPFH, $line, $length); | } | | close(OUTFH); | close(TMPFH); The "printf" is your culprit. It's probably eating every single %-escape and null character in the string. Replace that with print OUTFH $line and you'll be able to sleep at night. I know I do. :-) printf "%c%c%c%c%s",ord("J"),ord("u"),ord("s"),ord("t")," another Perl hacker," -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
kai@sp1.csrd.uiuc.edu (Kuck And Associates) (07/18/90)
al@ee.pitt.edu (Alan Martello) writes: >Why doesn't this work and how can it be modified to work? >while(<TMPFH>) >{ > printf OUTFH $line; > read(TMPFH, $line, $length); >} You're reading two lines at a time (the implied read in the "<TMPFH>" statement, and the read command), and only printing the second. How about: while (! eof(TMPFH)) { read (TMPFH, $line, 4096); print OUTFH $line; } Patrick Wolfe (pat@kai.com, kailand!pat) System Programmer/Operations Manager, Kuck & Associates "Any opinions expressed are my own, not my employers's. Please don't call my boss and complain ... again."
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (07/18/90)
In article <8120@pitt.UUCP> al@ee.pitt.edu (Alan Martello) writes: : I give up. I want to pipe binary data from one program to another : while (possibly) filtering it. : : Why doesn't this work and how can it be modified to work? : : ------------------------------------------------------------------------ : --------- : #!/bin/perl -P : : # : # this works (of course) since the shell does the pipe : # : system("cat /vmunix | dd of=./vmunix_copy1"); : : # : # how can I make perl do the same thing explicitly ? : # THIS DOESN'T WORK : # : open(TMPFH,"cat /vmunix | "); : open(OUTFH, "| dd of=./vmunix_copy2"); : : while(<TMPFH>) : { : printf OUTFH $line; : read(TMPFH, $line, $length); : } : : close(OUTFH); : close(TMPFH); It doesn't work because you're thinking of <TMPFH> as a test of whether there's more in the file. It does that, but it does it by reading a line's worth into $_, which the above loop then discards. You also shouldn't use printf on a line that might contain spurious % characters--naughty even in C. It also looks like you didn't initialize $length. Also, there's little point in opening "cat /vmunix |" when you can just open "/vmunix", but I understand it's just an example. Say either while(<TMPFH>) # reads file in random sized chunks { print OUTFH $_; } or $length = (stat(TMPFH))[11] || 8192; while (read(TMPFH, $line, $length)) { print OUTFH $line; } For a binary file, if it's not too big, you might just want to say undef $/; # slurp whole file (requires patchlevel 12) $_ = <TMPFH>; s/foo/bar/g; # sample filtration print OUTFH $_; Larry