Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

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:

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);


Comment on Re: Perl Path Editor for Unix
Select or Download Code
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
    > setpath.pl --/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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (10)
As of 2015-07-07 02:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (86 votes), past polls