#!/usr/bin/perl use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC); use Getopt::Std; my %opt; getopts("F", \%opt) or usage(); my $command = shift @ARGV or usage(); my $pat = '\.gz$'; my @fh; my @old; for my $file (@ARGV) { if ($file =~ /$pat/o && -f $file) { my $fh; unless (open($fh, "-|", "gzip", "-cd", $file)) { warn "Couldn't open file '$file': $!; skipping\n"; next; } push @fh, $fh; my $fd = fileno $fh; my $flags = fcntl($fh, F_GETFD, 0); fcntl($fh, F_SETFD, $flags & ~FD_CLOEXEC); my $oldfile = $file; $file = "/proc/self/fd/$fd"; $old[$fd] = $oldfile; # warn "$oldfile -> $file\n"; } } # warn "running $command @ARGV\n"; if ($opt{F}) { open my($out), "-|", $command, @ARGV or die "Couldn't run '$command': $!.\n"; while (<$out>) { s{/proc/self/fd/(\d+)}{$old[$1]}g; print; } if (close($out)) { exit; } elsif ($! == 0) { exit $? >> 8; } else { exit 2; } } else { exec $command, @ARGV; die "Couldn't run '$command': $!.\n"; } sub usage { print STDERR "Usage: $0 [-F] command args... \t-F: try to transform filenames in output back to original filenames\n"; exit 1; }