gri6507 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I didn't see any references to this seemingly trivial task anywhere within these gates, so I figure I'll ask. My $PATH environment variable became exceedingly long (after being modified in various scripts that are sourced at start of a new terminal). So, I figured that it would be easier to write a single perl script to clean this up rather than tracking every sourced file and cleaning the $PATH up by hand.

The script is done, but how do I set the terminal environment $PATH from within the script? If I just set $ENV{PATH}, that change goes away with termination of the script. There do not seem to be any "export" or "setenv" commands in perl.

btw, my shell is bash.

Replies are listed 'Best First'.
Re: Script to change $ENV{PATH}
by VSarkiss (Monsignor) on May 07, 2003 at 18:52 UTC

    Changes to environment variables are only passed down to child processes in Unix. Therefore, without taking some special steps, any changes your Perl program makes to your environment won't be reflected back to the calling shell program. A typical way to do something like this is to have your program output a bash command on its stdout, and eval that in bash.

    For example, your bash line in .profile or .bashrc would be:eval `path_munch.pl`where the basic structure of path_munch.pl (bad name, I know) is:

    #! /usr/bin/perl -w my @newpath; foreach (split /:/, $ENV{PATH}) { push @newpath, ... # however you do this } print 'export PATH=', join(':', @newpath), "\n";
    (Note, this is untested code).

    HTH

Re: Script to change $ENV{PATH}
by Zaxo (Archbishop) on May 07, 2003 at 22:57 UTC

    This is a case where you want to use the shell (VSarkiss++ has told you why). The shell 'source' operator, '.' (dot) will let you read a file of bash statements into the current environment. See 'man bash'.

    For instance, to regain much of your startup environment:

    $ . ~/.bash_profile $

    After Compline,
    Zaxo

Re: Script to change $ENV{PATH}
by TheHobbit (Pilgrim) on May 08, 2003 at 09:47 UTC
    Hi,
    The solution proposed by VSarkiss is interesying, but it has two drawbacks. First, it only applies to bash or sh, and second, does not generalize to other PATH like variables. I think this one solves these problems.

    • Put the following in your .profile if you are using sh or bash:
      PATH =`munch.pl $PATH`
      This is replaced by:
      setenv PATH `munch.pl $PATH`
      to put in .cshrc if you are using csh or tcsh.
    • The munch.pl script (why, VSarkiss, I like that name:)) is something like this:
      #!/usr/bin/perl -w use strict; my @comp = split /:/,shift; my %saw = (); @saw{@comp} = (); print join ":",keys %saw;

    This gives the following under bash:

    $ TEST="a:b:c:a:c:z:a:b:z" $ echo $TEST a:b:c:a:c:z:a:b:z $ TEST=`tmp/test.pl $TEST` $ echo $TEST a:z:b:c
    and the following under csh:
    > setenv TEST "a:b:c:a:c:z:a:b:z" > echo $TEST a:b:c:a:c:z:a:b:z > setenv TEST `tmp/test.pl $TEST` > echo $TEST a:z:b:c

    Hope that helps....

    Cheers


    Leo TheHobbit

      Argh.... I'm stupid today:) There is a big mistake in my post...

      The component order in PATH-like variables is important, sometimes very important, and my munch.pl script mess it up. This version of munch.it don't has this pitfall:

      #!/usr/bin/perl -w use strict; my @comp = split /:/,shift; my %saw = (); my @out = (); for (@comp) { push @out,$_ unless $saw{$_}++; } print join ":",@out;

      Now I may gonna hide in the monastery cellar...


      Leo TheHobbit
Re: Script to change $ENV{PATH}
by gri6507 (Deacon) on May 07, 2003 at 19:04 UTC
    Thanks. I thouhgt that might be the only way out.