add kvpairs2td
[hband-tools.git] / user-tools / redirexec
blob3d6d43d9b39598025e9b3a1676e117f7832f8a69
1 #!/usr/bin/env perl
3 use POSIX qw/dup2/;
5 $0 =~ s/.*\/([^\/]+)$/$1/;
7 %perlopenmode = (
8 'r' => {symbol => '<', word => 'read'},
9 'c' => {symbol => '>', word => 'create/clobber'},
10 'rw' => {symbol => '+<', word => 'read/write'},
11 'a' => {symbol => '>>', word => 'append'},
14 @redirs = ();
16 while(@ARGV)
18 my $fdspec = shift @ARGV;
19 if($fdspec eq '--') { last; }
20 if($fdspec =~ /^(?'fd'\d+|std(in|out|err)):(?'dest'-|(?'mode'r|c|rw|a):(file:(?'path'.+)|fd:(?'fileno'\d+|std(in|out|err))))$/)
22 my ($fd, $dest, $mode, $path, $fileno) = ($+{'fd'}, $+{'dest'}, $+{'mode'}, $+{'path'}, $+{'fileno'});
23 $fd = 0 if $fd eq 'stdin';
24 $fd = 1 if $fd eq 'stdout';
25 $fd = 2 if $fd eq 'stderr';
26 $fileno = 0 if $fileno eq 'stdin';
27 $fileno = 1 if $fileno eq 'stdout';
28 $fileno = 2 if $fileno eq 'stderr';
29 if($dest eq '-')
31 $mode = 'rw';
32 $path = '/dev/null';
34 push @redirs, {
35 fd => $fd,
36 mode => $perlopenmode{$mode}->{'symbol'} . (defined $fileno ? '&=' : ''),
37 modename => $perlopenmode{$mode}->{'word'},
38 file => defined $fileno ? $fileno : $path,
41 else
43 warn "invalid redirect specification: $fdspec\n";
44 pod2usage(-exitval=>2, -verbose=>99);
48 @command = @ARGV;
50 for my $redir (@redirs)
52 open $fh, $redir->{'mode'}, $redir->{'file'} or die "$0: can not open ($redir->{'modename'}) $redir->{'file'}: $!\n";
53 dup2(fileno $fh, $redir->{'fd'}) or die "$0: can not duplicate fd of $redir->{'file'}: $!\n";
56 exec {$command[0]} @command;
59 __END__
62 =pod
64 =head1 NAME
66 redirexec - Execute a command with some file descriptiors redirected.
68 =head1 SYNOPSIS
70 redirexec [I<FILENO>:I<MODE>:file:I<PATH>] -- I<COMMAND> I<ARGS>
72 redirexec [I<FILENO>:I<MODE>:fd:I<FD>] -- I<COMMAND> I<ARGS>
74 redirexec [I<FILENO>:-] -- I<COMMAND> I<ARGS>
76 =head1 DESCRIPTION
78 Setup redirections before executing I<COMMAND>.
79 You can setup the same type of file and file descriptor redirections as in shell.
81 I<FILENO> and I<FD> are file descriptor integers or literal "stdin", "stdout", or "stderr".
83 I<MODE> is one of:
85 =over 4
87 =item r
89 read
91 =item c
93 create/clobber
95 =item rw
97 read and write
99 =item a
101 append
103 =back
105 =head1 EXAMPLES
107 +-----------------+--------------------------+
108 | shell syntax | redirexec(1) equivalents |
109 +=================+==========================+
110 | > output.txt | stdout:c:file:output.txt |
111 | | 1:c:file:output.txt |
112 +-----------------+--------------------------+
113 | 2>&1 | stderr:c:fd:stdout |
114 | | 2:c:fd:1 |
115 +-----------------+--------------------------+
116 | </dev/null | 0:r:file:/dev/null |
117 | | 0:- |
118 +-----------------+--------------------------+
119 | >/dev/null 2>&1 | 1:- 2:- |
120 +-----------------+--------------------------+
123 =head1 SEE ALSO
125 redirfd by execlineb(1)
127 =cut