Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: Perl Path Editor for Unix

by graff (Chancellor)
on Sep 14, 2005 at 04:58 UTC ( #491763=note: print w/ replies, xml ) Need Help??

in reply to Perl Path Editor for Unix

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: [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: VAR1 :NEWPATH VAR2 OTHERPATH: VAR3 --BADPATH # # shell function would be: function setpath { /full/path/to/ $*; 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);

Replies are listed 'Best First'.
Re^2: Perl Path Editor for Unix
by greenFox (Vicar) on Sep 14, 2005 at 07:53 UTC

    Not quite matching your spec but here you go. I implemented as much as I would use...

    my %path; my ($high, $low) = (0,0); for (split /:/, $ENV{PATH} ){ next if exists $path{$_}; # remove duplicates $path{$_} = $high; ++$high; } for (@ARGV){ /^-(.*)/ and do {delete $path{$1} if exists $path{$1}; next;}; /^\+\+(.*)/ and do {--$low; $path{$1}=$low unless exists $path{$1}; +next;}; /^\+(.*)/ and do {++$high; $path{$1}=$high unless exists $path{$1}; +next;}; } print join ":", sort {$path{$a} <=> $path{$b} } keys %path; print "\n";

    Murray Barton
    Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho

Re^2: Perl Path Editor for Unix
by 5p1d3r (Hermit) on Sep 14, 2005 at 13:09 UTC
    That's a nice variation. I think the two could be combined with arguments used by default but falling back to interactive behavior in their absence.

    The regex path matching on a remove or remove all seems a little off:

    > export PATHTEST=/foo:/foobar:/foo/bar
    > --/foo
    > more .setpath.out
    export PATHTEST=:bar:/bar/
    This works if you append a ':' to the path you're removing (which I guess the script could do for you). It might be nice to add some sort of wild carding to the removals so you could remove every directory rooted at /foo.

    I initially wrote mine to do removes but for my usage I prefer to temporarily toggle directories on/off. The tools developers I work with chose executable names that match those of a number of gnu tools I make use of so on occassion I need to temporaily remove one or other directory from my PATH.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://491763]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (10)
As of 2016-06-28 16:43 GMT
Find Nodes?
    Voting Booth?
    My preferred method of making French fries (chips) is in a ...

    Results (359 votes). Check out past polls.