Tom Christiansen <tchrist@convex.COM> (06/06/91)
(Put followups wherever you want -- I just didn't want them to land in alt.sources unless they were also source.) From the keyboard of dkeisen@leland.Stanford.EDU (Dave Eisen): :In article <1991Jun6.093939.9346@dartvax.dartmouth.edu> pete@othello.dartmouth.edu (Pete Schmitt) writes: :>Is there a tee like program that will pipe down to another program? :> : :Sure. It's called "tee". : :Something like: : :program1 | tee /dev/tty | program2 : :should do what you want. I suspect that this is not want the original poster wanted. While its true that it does work in this case, it's not going to work if you want to "tee off" to a list of processes. Here's a program that's a supersets of the original tee, so I think you can just put it in your own bin and call it tee; I did.. Instead of just file specs, you can give pipe specs like this "|program". So for the simple suggestion above, the usage would be program1 | tee "|program2" which isn't particularly interesting. This is: program1 | tee "|program2" "|program3" "|program4" It still understands -a for append and -i for ignoring interrupts (which I've never used), as well as a new -u for "unbuffered" output, especially useful with pipes. You can also mix your appends and overwrites by specifying ">>file" for appending. "file" is the same as ">file", unless the -a flag is on, in which case it's ">>file". You can always use ">file" or ">>file" to override the default. For example, not using any defaults: $ prog1 | tee -u ">file1" "|prog2" ">>file2" "|prog3 | prog4" ">file3" ">>file4" prog1 runs into tee, which duplicates its output to several different places. first, a copy goes to stdout (redirect into /dev/null if you don't want this.) file1 and file3 get overwritten, file2 and file4 get appended to, and prog2 and prog3 get run. oh, and prog3 runs into prog4. Program follows; not bad for ~30 lines of code, eh? :-) --tom #!/usr/bin/perl # # tee clone that groks process tees (should work even with old perls) # Tom Christiansen <tchrist@convex.com> # 6 June 91 while ($ARGV[0] =~ /^-(.+)/ && (shift, ($_ = $1), 1)) { next if /^$/; s/i// && (++$ignore_ints, redo); s/a// && (++$append, redo); s/u// && (++$unbuffer, redo); die "usage tee [-aiu] [filenames] ...\n"; } if ($ignore_ints) { for $sig ('INT', 'TERM', 'HUP', 'QUIT') { $SIG{$sig} = 'IGNORE'; } } $mode = $append ? '>>' : '>'; $fh = 'FH000'; %fh = ('STDOUT', 'standard output'); # always go to stdout $| = 1 if $unbuffer; for (@ARGV) { if (!open($fh, (/^[^>|]/ && $mode) . $_)) { warn "$0: cannot open $_: $!\n"; # like sun's; i prefer die $status++; next; } select((select($fh), $| = 1)[0]) if $unbuffer; $fh{$fh++} = $_; } while (<STDIN>) { for $fh (keys %fh) { print $fh $_; } } for $fh (keys %fh) { close($fh) && next; warn "$0: couldn't close $fh{$fh}: $!\n"; $status++; } exit $status; -- Tom Christiansen tchrist@convex.com convex!tchrist "Perl is to sed as C is to assembly language." -me
tchrist@convex.COM (Tom Christiansen) (06/07/91)
It might be nice to get better than an ungraceful death by SIGPIPE if a pipe kid dies or never gets started. Here's a patch to trap this: 16a17 > $SIG{'PIPE'} = 'PLUMBER'; 37c38 < close($fh) && next; --- > next if close($fh) || !defined $fh{$fh}; 41a43,48 > > sub PLUMBER { > warn "$0: pipe to \"$fh{$fh}\" broke!\n"; > $status++; > delete $fh{$fh}; > } --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "Perl is to sed as C is to assembly language." -me
pete@altair.dartmouth.edu (Pete Schmitt) (06/07/91)
All I want to do is: cat file | tee program_1 | program_2 Is there a program that will do this? -pete schmitt
djm@eng.umd.edu (David J. MacKenzie) (06/07/91)
> cat file | tee program_1 | program_2
This oughta work (I say without testing):
mknod mypipe p
program_1 < mypipe &
cat file | tee mypipe | program_2
rm mypipe
or, not needing cat, replace the third line with:
tee mypipe < file | program_2
--
David J. MacKenzie <djm@eng.umd.edu> <djm@ai.mit.edu>
Tom Christiansen <tchrist@convex.COM> (06/07/91)
From the keyboard of pete@altair.dartmouth.edu (Pete Schmitt): :All I want to do is: : :cat file | tee program_1 | program_2 : :Is there a program that will do this? My tee clone will: tee "|program_1" "|program_2" < file > /dev/null # toss stdout --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "Perl is to sed as C is to assembly language." -me