Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Can I do this ???

by Anonymous Monk
on Jan 22, 2009 at 11:09 UTC ( [id://738111]=perlquestion: print w/replies, xml ) Need Help??

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

I have a problem here .. i know that through child process I cant modify parents' variables. But just asking if there is a way ... Here is the problem: Perl script sets a $ENV{'SSD'} variables & calls system command to invoke a shell script system("sh s01.sh") Shell script echoes the variable set by perl script echo $SSD This works fine But if I modify the value of the $SSD in shell script .. no change seen in perl script .. Is there a way to make it work?? Thanks

Replies are listed 'Best First'.
Re: Can I do this ???
by bingos (Vicar) on Jan 22, 2009 at 11:21 UTC

    The simple answer is 'No'. Child processes get a copy of the parent's environment, see this

    Apparently it is vaguely possible on MSWin32 with some craftiness

Re: Can I do this ???
by grinder (Bishop) on Jan 22, 2009 at 14:03 UTC

    You can do this with a little cooperation between different processes. Consider the following:

    #! /bin/sh perl prog1 -x ./env.sh foo bar [ -f ./env.sh ] && ./env.sh perl prog2 quux

    The idea is that prog1 writes valid shell commands to the env.sh file, does whatever else it has to do and then exits. Execution flow returns to the outer shell, which then sources the file that it wrote.

    The prog2 program then runs, and picks up what ever environment changes were made by env.sh.

    This is rather fragile and insecure. If you are brave and insist on this approach you really should consider using IPC (Inter-Process Communication) for a more robust solution. The idea is to create a channel of communication (child writes, parent reads) between the two. See perlipc for more information.

    • another intruder with the mooring in the heart of the Perl

      grinder++ I agree with you, that parents cooperating with children can cause a change in the parents environment. Hey, that probably holds true in real life as well...

      My contribution here is that I implemented something similar, using unix signals. The parent would trap on an unused signal (I used SIGUSR1) and read-in-and-execute all the commands contained in a pre-defined temporary file.

      When the child wanted to change something in the parents environment, it would write those changes to the pre-defined temporary file, then would poke-the-parent-in-the-side by sending a signal via the unix kill(1) command.

      This worked well for me.

      -Craig

Re: Can I do this ???
by JavaFan (Canon) on Jan 22, 2009 at 11:16 UTC
    Only by switching to an OS that passes environmental changes to parent processes. The perlfaq used to suggest that it was possible in VMS. But it isn't possible in any Unix or Windows platform.
Re: Can I do this ???
by cdarke (Prior) on Jan 22, 2009 at 12:42 UTC
    Win32::EnvProcess on Windows, but it can be a bit flaky. Try as I might I cannot hack a way of doing that in *nix, even by attaching as a debugger.

    You really need co-operating processes and some sort of perlipc.

    update: For example (untested):
    my $status = system('(shs01.sh;thing.pl)');
    The 'thing.pl' perl script runs in the same subshell as the script, and should be able to pickup environment variable changes. It can then use some sort of IPC to pass the env. block back to the parent (or even save it in a file).
Re: Can I do this ???
by rovf (Priest) on Jan 22, 2009 at 12:56 UTC
    i know that through child process I cant modify parents' variables. But just asking if there is a way

    Fortunately not. I would feel very uneasy as a programmer if I had to worry whether my child processes secretly change my environment without me noticing. This is already pretty nasty in Windoze batch programming where this "feature" is possible.

    IMHO, values should passed back to the parent in a way which is clearly visible (i.e. the caller has to ask for the values). How this is done, depends on the application being called. For instance, you might pass a filename to the application, and it writes any output parameters into the file. Or, the application uses stdout to pass data back, and you use qx() instead of system() to catch it.

    -- 
    Ronald Fischer <ynnor@mm.st>
      This is already pretty nasty in Windoze batch programming where this "feature" is possible.

      It is?

      > type foo.cmd perl -le "print q{FOOBAR=}, $ENV{FOOBAR}" perl -e "$ENV{FOOBAR}=rand(9999)" perl -le "print q{FOOBAR=}, $ENV{FOOBAR}"

      This produces

      FOOBAR= FOOBAR=

      Which seems to show that things are working as expected. Either that, or I suck at writing Windows batch files.

      • another intruder with the mooring in the heart of the Perl

        Windows batch processing.

        @REM -------------------------------- @REM runme.cmd @echo off SET FOO=bar echo %FOO% echo Calling setter.cmd call setter.cmd echo After setter.cmd echo %FOO%
        @REM --------------------------------- @REM setter.cmd echo "I am in setter." set FOO=biz echo Setters FOO = %FOO%
        -------------------------------------- output -------------------------------------- bar Calling setter.cmd "I am in setter." Setters FOO = biz After setter.cmd biz

        The called sub command, setter.cmd, resets the environment of the caller.

        --MidLifeXis

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://738111]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-25 23:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found