docs clarification
[hband-tools.git] / user-tools / args2env
blobff0b35474b14dbea4ec84e173446ee2ae39571b4
1 #!/usr/bin/env perl
3 =pod
5 =head1 NAME
7 args2env - Turns command arguments into environment variables and executes command with the remained arguments
9 =head1 SYNOPSIS
11 args2env [I<OPTIONS>] I<COMMAND> I<ARG_1> I<ARG_2> ... I<ARG_R2> I<ARG_R1>
13 =head1 DESCRIPTION
15 =head1 OPTIONS
17 =over 4
19 =item -a, --arg I<NUM>
21 Move the I<NUM>th argument to the environment by the name B<< ARG_I<NUM> >>
22 (may be overridden by B<--template> option).
23 Counting starts from 1.
24 The 0th argument would be the I<COMMAND> itself.
25 I<NUM> may be negative number, in which case it's counted from the end backwards.
27 =item -r, --right-arg I<NUM>
29 Same as B<< --arg -I<NUM> >>.
31 =item -A, --all
33 Move all arguments to environment.
35 =item -k, --keep I<NUM>
37 Keep the first I<NUM> arguments as arguments, and move the rest of them to environment.
38 Don't use it with B<-A>, B<-a>, or B<-r>.
40 =item -t, --template I<TEMPLATE>
42 How to name environment variables?
43 Must contain a B<%d> macro.
44 Default is B<ARG_%d>.
45 So the value of argument given by B<--arg 1> goes to B<ARG_1> variable.
47 =item -nt, --negative-template I<TEMPLATE>
49 How to name environment variables for arguments specified by negative number?
50 Must contain a B<%d> macro.
51 Default is B<ARG_R%d>, B<R> is for "right", because this arg is counted from the right.
52 So the value of argument given by B<--arg -1> goes to B<ARG_R1> variable.
54 =item -s, --set I<NAME>=I<NUM>
56 Set I<NAME> variable to the I<NUM>th argument (negative numbers also may be given)
57 and remove the argument from the argument list (keeping the numbering of remaining arguments unchanged).
58 Number-based variables (B<< ARG_I<n> >> and B<< ARG_RI<n> >>) are still available.
60 =back
62 =head1 SEE ALSO
64 args2stdin(1)
66 =cut
69 use Data::Dumper;
70 use Errno qw/:POSIX/;
71 use Getopt::Long qw/:config no_ignore_case no_bundling no_getopt_compat no_auto_abbrev require_order/;
72 use Pod::Usage;
73 no if ($] >= 5.018), 'warnings' => 'experimental::smartmatch';
75 @args_to_move = ();
76 @OptSetenv = ();
77 $OptKeepArgs = undef;
78 %env_names = ();
79 $envname_template = 'ARG_%d';
80 $negative_envname_template = 'ARG_R%d';
82 GetOptions(
83 'a|arg=i@' => \@args_to_move,
84 'A|all' => sub { $OptKeepArgs = 0; },
85 'k|keep=i' => \$OptKeepArgs,
86 'r|right-arg=i@' => sub {
87 my ($getopt, $param) = @_;
88 push @args_to_move, -$param;
90 's|set=s@' => \@OptSetenv,
91 't|template=s' => \$envname_template,
92 'nt|negative-template=s' => \$negative_envname_template,
93 'help' => sub { pod2usage(-exitval=>0, -verbose=>99); },
94 ) or pod2usage(-exitval=>2, -verbose=>99);
96 if(defined $OptKeepArgs)
98 @args_to_move = (($OptKeepArgs+1) .. $#ARGV);
101 for my $setenv (@OptSetenv)
103 if(my ($name, $num) = $setenv =~ /^([^=]+)=(-?\d+)$/)
105 push @args_to_move, $num;
106 $env_names{$num} = $name;
108 else
110 die "$0: wrong --set option: $setenv\n";
114 if(grep {$_ == 0} @args_to_move)
116 warn "The 0th argument is the command itself, better not to remove.\n";
117 pod2usage(-exitval=>2, -verbose=>99);
120 for my $arg_num (1..$#ARGV)
122 if(grep {$_ > 0 ? ($arg_num == $_) : ($arg_num == scalar(@ARGV)+$_)} @args_to_move)
124 my $arg_num_neg = $arg_num - scalar(@ARGV);
125 for my $n ($arg_num, $arg_num_neg)
127 $ENV{$env_names{$n}} = $ARGV[$arg_num] if defined $env_names{$n};
129 my $envname_pos = sprintf $envname_template, $arg_num;
130 my $envname_neg = sprintf $negative_envname_template, abs $arg_num_neg;
131 $ENV{$envname_pos} = $ARGV[$arg_num];
132 $ENV{$envname_neg} = $ARGV[$arg_num];
133 $ARGV[$arg_num] = undef;
136 @ARGV = grep {defined} @ARGV;
138 exec {$ARGV[0]} @ARGV;
139 ($errno, $errstr) = (int $!, $!);
140 warn "$0: ${ARGV[0]}: $errstr\n";
141 exit 125+$errno;