- if [ $# -eq 0 ]; then exec perl -x -S $0; exit $? ; else exec perl -x -S $0 "$@"; exit $? ; fi
- #!/bin/perl
- #optpath - eliminate path components that do not exist on this host.
-
- #################################### MAIN ######################################
-
- &init_pathname();
- &parse_args;
-
- &init_env($VAR_ARG, $SEP_ARG);
-
- $newpath = "";
- %upath = ();
-
- #for each path component...
- foreach $pp (@PATH)
- {
- #printf STDERR "pp=%s\n", $pp;
- next if (defined($upaths{$pp})); #been there, done that
- next if (!(-d $pp) && !(-f $pp) && $DELETE_OPTION);
-
- if ($RM_OPT == 1) {
- $yesmatch = 0;
- foreach $pat (@RM_LIST) {
- $yesmatch = ($pp =~ /$pat/);
- #printf STDERR "pat=%s pp=%s yesmatch=%d\n", $pat, $pp, $yesmatch;
- last if ($yesmatch);
- }
-
- next if ($yesmatch);
- }
-
- $upaths{$pp} = 1;
- $newpath = ($newpath eq "") ? $pp : "${newpath}$SEP_ARG${pp}";
- }
-
- print "$newpath\n";
- exit 0;
-
- ################################# INIT,USAGE ###################################
-
- sub usage
- {
- local($status) = @_;
-
- print STDERR <<"!";
- Usage: $p [-help] [-d] -var PATHVAR -sep PATHSEP
- [-rm pattern[,pattern ...]]
-
- Synopsis:
- Edit a PATH variable, eliminating redundant components,
- while preserving precedence.
-
- Options:
- -help display usage message.
- -d delete non-existent components from path.
- -var PATHVAR
- use <PATHVAR> instead of the standard command PATH variable.
- -sep PATHSEP
- use <PATHSEP> instead of the standard command PATH separator char.
- -rm pattern[,pattern ...]
- remove path components matching any pattern in the supplied
- pattern list. Individual patterns are interpreted as perl
- regular-expressions.
-
- Examples:
- Typical use at end of .cshrc or .tcshrc:
-
- set opt=`$p` >& /dev/null
- if (\$status == 0) then
- setenv PATH \$opt
- else
- echo path not optimized
- endif
-
- At end of .profile (/bin/sh) or profile.ksh (mks shell):
-
- opt=`optpath`
- if [ $? -eq 0 ]; then
- PATH=$opt
- else
- echo path not optimized
- fi
-
- Delete components that begin with "/home/d/tools",
- or end with "/bin/cmn", "/bin/\$OWARE_ROOT", or "/install/bin".
- Note the careful quoting. This allows the shell to interpolate
- \$OWARE_ROOT, while passing \$ as part of the perl pattern:
-
- set opt=`$p -rm '^/home/d/tools,/install/bin\$,/bin/'\${OWARE_ROOT}'\$'`
-
- Edit the Java CLASSPATH variable, deleting non-existent
- class directories and archives:
-
- set opt=`$p -d -var CLASSPATH -sep ':'`
-
- NOTES:
- Please check the status of the $p command
- before resetting your path - otherwise your shell
- may become unusable.
-
- Care must be taken with the -d option. Sometimes
- path components are not present because they have
- not been built yet, or because the network is
- temporarily unavailable.
-
- !
- exit($status);
- }
-
- sub parse_args
- #proccess command-line aguments
- {
- local ($flag, $parm);
- $DELETE_OPTION = 0;
- $RM_OPT = 0;
- $SEP_OPT = 0;
- $VAR_OPT = 0;
-
- #default to standard path var & separator:
- $VAR_ARG = $PATHVAR;
- $SEP_ARG = $CPS;
-
- #eat up flag args:
- while ($#ARGV+1 > 0 && $ARGV[0] =~ /^-/) {
- $flag = shift(@ARGV);
-
- if ($flag eq '-d') {
- $DELETE_OPTION = 1;
- } elsif ($flag =~ '^-h') {
- &usage(0);
- } elsif ($flag eq '-var') {
- if ($#ARGV < 0 || $ARGV[0] eq "") {
- printf STDERR "%s: -var requires an argument\n", $p;
- &usage(1);
- }
- $VAR_OPT = 1;
- $VAR_ARG = shift(@ARGV);
- } elsif ($flag eq '-sep') {
- if ($#ARGV < 0 || $ARGV[0] eq "") {
- printf STDERR "%s: -sep requires an argument\n", $p;
- &usage(1);
- }
- $SEP_OPT = 1;
- $SEP_ARG = shift(@ARGV);
- } elsif ($flag eq '-rm') {
- if ($#ARGV < 0 || $ARGV[0] eq "") {
- printf STDERR "%s: -rm requires an argument\n", $p;
- &usage(1);
- }
- $RM_OPT = 1;
- @RM_LIST = split(',', shift(@ARGV));
- } else {
- &usage(1);
- }
- }
-
- #ignore any other args...
- }
-
- sub init_env
- {
- local($pathvar, $pathsep) = @_;
- local ($path) = $ENV{$pathvar};
-
- #printf STDERR "init_env: OS=%d pathvar='%s'\n", $OS, $pathvar;
-
- #convert to lower case if NT:
- $path =~ tr/A-Z/a-z/ if ($OS == $NT);
-
- #get path environment var:
- @PATH = split($pathsep, $path);
-
- if ($#PATH < 0) {
- printf STDERR ("%s: can't get path variable!\n", $p);
- exit(1);
- }
- }
-
- ################################ PATH UTILITIES ###############################
-
- sub pickfiles
- #pick the plain file entries from a directory listing.
- #<lsout> must be in CWD or contain full path refs.
- #list returned in <thefiles>.
- {
- local (*thefiles, *lsout) = @_;
-
- @thefiles = grep(!(-d $_), @lsout);
- }
-
- sub pwd
- #return full pathname of current working directory.
- {
- local ($tmp);
- if ($OS == $UNIX) {
- $tmp = (`pwd`);
- chop $tmp;
- return($tmp);
- }
-
- return("NULL"); #not handled
- }
-
- sub ls
- #<lsout> <-- `ls <dir>`
- {
- local (*lsout, $dir) = @_;
-
- if (!opendir(DIR, $dir)) {
- @lsout = ();
- return;
- }
-
- #skip '.' & '..' on unix
- @lsout = grep(!/^\.\.?$/,readdir(DIR));
-
- closedir(DIR);
- }
-
- sub path_separator
- #what is the separator char used by this filesystem, and how is
- #the current directory indicated?
- #Returns 9-tuple:
- # (current_dir_symbol,
- # volume_separator,
- # input_path_separator,
- # output_path_separator,
- # up_directory,
- # command_PATH_env_var_separator,
- # command_LIBPATH_env_var_separator,
- # PATH_ENV_VAR_NAME
- # )
- {
- $UNIX = 1; $NT=2;
-
- $OSENV = $ENV{'OS'};
- ## if ((defined($OSENV) && $OSENV eq 'Windows_NT') || $0 =~ /\.ksh$/) {
- ## $OS = $NT;
- ## return('.', ':', '[\\\/]', '/', '..', ';', ';', 'PATH');
- ## }
-
-
-
- #default is unix:
- $OS = $UNIX;
- return('.', '/', '/', '/', '..', ':', ';', 'PATH');
- }
-
- sub init_pathname
- #initialize standard pathname variables.
- {
- ($DOT, $VOLSEP, $PS_IN, $PS_OUT, $UPDIR, $CPS, $LIBPS, $PATHVAR) = &path_separator;
-
- #set up program name argument:
- local(@tmp) = split($PS_IN, $0);
- # figure out the program name and put it into p
- $p = $tmp[$#tmp];
- $p =~ s/\.ksh$// if ($OS == $NT);
- }
-
- sub mkpathname
- #convert a list of pathname components to a local path name.
- {
- local (@plist) = @_;
-
- #strip trailing input path-separators:
- for ($ii=0; $ii<=$#plist; $ii++) {
- $plist[$ii] =~ s/${PS_IN}$//;
- }
-
- return(join($PS_OUT, @plist));
- }
-