I like this idea, but I think that having to face an interactive dialog with a perl script via STDIN every time I use it would give me a headache.
It wouldn't be that hard to adapt it so that @ARGV has all the information needed for just about every case -- e.g. consider a usage summary like this:
setpath.pl [ENV_VAR] [:NEWPATH | NEWPATH: | -[-]OLDPATH]
Default ENV_VAR is PATH
:NEWPATH appends ":NEWPATH" at end of ENV_VAR
NEWPATH: prepends "NEWPATH:" at start of ENV_VAR
-OLDPATH deletes first instance of "OLDPATH" from ENV_VAR
--OLDPATH deletes all instances of "OLDPATH" from ENV_VAR
Conceivably, you could handle multiple path args to be added or removed from the given variable in a single command line. For that matter, you could even do multiple variables on one command line:
setpath.pl VAR1 :NEWPATH VAR2 OTHERPATH: VAR3 --BADPATH
#
# shell function would be:
function setpath { /full/path/to/setpath.pl $*; if ... };
Maybe "chpath" would be a better name for the shell function.
update: Here is how I would do the @ARGV-based approach -- just a first attempt (I probably need to test more, esp. the regex for matching "valid" path args), but when combined with the appropriate shell function to use it, I think it would be serviceable for most needs. To me, it just seems a lot cleaner without all that prompting and reading user input on STDIN.
#!/usr/bin/perl
use strict;
my $Usage = <<ENDUSE;
Usage: $0 [ENV_VAR] [:NEWPATH | NEWPATH: | -[-]OLDPATH] ...
default ENV_VAR is PATH
:NEWPATH add NEWPATH at end of ENV_VAR
NEWPATH: add NEWPATH at start of ENV_VAR
-OLDPATH delete first instance of OLDPATH from ENV_VAR
--OLDPATH delete all instances of OLDPATH from ENV_VAR
You may add/remove multiple path strings from a single ENV_VAR,
and you may change multiple ENV_VARs with one command, e.g.:
$0 VAR1 /new/path: VAR2 --/bad/path :/good/path
ENDUSE
my %env_change;
my $varname = 'PATH';
my $pathrgx = qr{(?:\.{0,2}/)+\.?\w.+};
for ( @ARGV ) {
my $edit_op =
( m{ ^:$pathrgx$ }x ) ? 'append' :
( m{ ^$pathrgx:$ }x ) ? 'prepend' :
( m{ ^-($pathrgx)$ }x ) ? 'rm1st' :
( m{ ^--($pathrgx)$ }x ) ? 'rmall' : '';
if ( substr( $edit_op, 0, 2 ) eq 'rm' ) {
push @{$env_change{$varname}{$edit_op}}, $1;
}
elsif ( $edit_op ) {
$env_change{$varname}{$edit_op} .= $_;
}
elsif ( /^\w+$/ ) {
$varname = $_;
}
else {
warn "$_ is not a valid ENV variable or path string\n";
die $Usage;
}
}
my $home = $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($<))[7];
my $fName = "$home/.setpath.out";
if ( -e $fName ) {
unlink ( $fName )
or die( "Unable to unlink previous $fName file ($!)\n" );
}
open( OUT, "> $fName" );
for $varname ( keys %env_change ) {
my $varval = '';
if ( ! length( $ENV{$varname} )) {
$varval = $env_change{$varname}{prepend} .
$env_change{$varname}{append};
if ( $varval eq '' ) {
warn "No additions to non-existent $varname; skipping that
+...\n";
next;
}
}
else {
if ( exists( $env_change{$varname}{rmall} )) {
$ENV{$varname} =~ s/$_//g for ( @{$env_change{$varname}{rm
+all}} );
}
if ( exists( $env_change{$varname}{rm1st} )) {
$ENV{$varname} =~ s/$_// for ( @{$env_change{$varname}{rm1
+st}} );
}
$varval = join( ':',
$env_change{$varname}{prepend},
split( /:+/, $ENV{$varname} ),
$env_change{$varname}{append} );
}
$varval =~ s/^://;
$varval =~ s/:$//;
$varval =~ s/:{2,}/:/g;
print OUT "export $varname=$varval\n";
}
exit(0);
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.