Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Problem piping binary data Message-ID: <8773@jpl-devvax.JPL.NASA.GOV> Date: 18 Jul 90 00:38:37 GMT References: <8120@pitt.UUCP> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 62 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() : { : printf OUTFH $line; : read(TMPFH, $line, $length); : } : : close(OUTFH); : close(TMPFH); It doesn't work because you're thinking of 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() # 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) $_ = ; s/foo/bar/g; # sample filtration print OUTFH $_; Larry