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

I have a Linux kernel hack which causes special behavior based on a process's environment. Strangely, unix kernels are aware of each process's environment, and with Linux it is visible as /proc/*/environ. The hack works wonderfully.

My problem is I am writing test regression scripts in perl. Modifying %ENV doesn't actually call setenv() to change it for the OS to see, thus my kernel trick is not tested. How can I make perl "flush" the environment?

The perlvar man page says fork() causes the children to receive environment updates, but in my testing it is exec() which does the magic. Damn.

Sadly, calling system() or qx// or something that calls exec() does not flush the environment of the parent, only the child. :-(

In other words, I challenge you to modify /proc/self/environ in perl without calling exec().

Replies are listed 'Best First'.
Re: true environment
by Zaxo (Archbishop) on Oct 30, 2003 at 03:13 UTC

    Did you try it in a simple enough form that other errors don't get in the way? $ perl -e'$ENV{FOO} = q(bar);print `cat /proc/self/environ`,$/' produces a long bunch of stuff whose last entry is FOO=bar. The /proc/self/environ file is read-only to its owner.

    After Compline,
    Zaxo

      But that shows the environment of the cat process, which is a child of the perl process (a fork() and exec() happens behind the scenes), and the OP wanted to inspect the (changed) environment of the parent.

      Abigail

Re: true environment
by PodMaster (Abbot) on Oct 30, 2003 at 03:33 UTC
    Maybe you want to look into Env::C

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: true environment
by ptkdb (Monk) on Oct 30, 2003 at 13:09 UTC
    (trying this against systems currently at my fingers, my linux boxes are at home)

    Perhaps it's different on Linux, but on Aix(perl 5.8.0) and Solaris 2.6(perl 5.6.1)

    $ENV{FOO}='bar' ; system('echo $FOO') ;
    produced:
    bar

    On Win2k(perl 5.6.1) you have to change $FOO to %FOO% but you get the same result.

    This suggests to me that the environment is getting altered and picked up the the child processes of the perl script.

Re: true environment
by what (Initiate) on Oct 31, 2003 at 19:55 UTC
    This has nothing to do with perl. /proc/$$/environ is only the environment that the process was started in. %ENV does properly export variables, environ simply never changes after a process has started. Observe:

    $ perl -e'%ENV=();exec "sh --noprofile"' $ cat /proc/$$/environ $ export FOO=sausage $ cat /proc/$$/environ $ sh --noprofile $ cat /proc/$$/environ FOO=sausage $ perl -e'%ENV=(BAR => "sausage");exec "sh --noprofile"' sh-2.05b$ cat /proc/$$/environ BAR=sausage


    Perl works as expected, /proc/$$/environ simply isn't what you thought it was.
Re: true environment
by benizi (Hermit) on Oct 31, 2003 at 20:07 UTC

    setenv() itself doesn't seem to update /proc/pid/environ. I tried it in C, doing a setenv and a sleep so I could cat /proc/pid/environ from a separate shell. I also tried using fork() and checking /proc/child_pid/environ. No luck. In both cases, getenv() worked right (the value was updated in the parent and the child).