Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

sourcing a shell script/.profile and importing into %ENV

by gnu@perl (Pilgrim)
on Mar 21, 2003 at 17:01 UTC ( #244933=perlquestion: print w/replies, xml ) Need Help??
gnu@perl has asked for the wisdom of the Perl Monks concerning the following question:

I have a program that is run as root and for certain tasks it changes $> to become another user then goes back to root for more work. This all works fine, except for one thing. The user that I change to needs to have it's environment updated with new $PATH info as well as some new environmental variables.

It's not hard to code them into the program, but that causes a problem. The environmental variables that need to be set get changed from time to time. The .profile of the user I become (in the new assignment to $>) is of course sourced for that user when they log in. In my script the simple assignment of their UID to $> does not do this, so many of the routines fail.

Does anyone know of a way to source a .profile while in a perl script? This .profile runs some commands and programs to set things, so it's not as easy as just picking out the relavent parts and adding them to %ENV.

Please don't take offense, but I do not want this to turn into a security debate. I do realize that doing this is a security risk. I just need to know how/if it can be done.

TIA, Chad.

  • Comment on sourcing a shell script/.profile and importing into %ENV

Replies are listed 'Best First'.
Re: sourcing a shell script/.profile and importing into %ENV
by ChemBoy (Priest) on Mar 21, 2003 at 19:51 UTC

    It isn't pretty, something along these lines should do the trick:

    #!/usr/bin/perl $sourcefile = "/etc/"; # or whatever chomp(@newenv = qx ( . $sourcefile; env) ); foreach (@newenv) { ($k,$v) = split "=",$_,2; $ENV{$k}=$v; }

    If God had meant us to fly, he would *never* have given us the railroads.
        --Michael Flanders

      I must apologize to ChemBoy. In my haste with another issue I misread his post. This will work quite well. Thank you.

      yay++ ChemBoy

      this is also way useful when your *$@*$ sysadmin people only create setup.csh scripts for applications and not the equivalent scripts...

      Thanks for your input, but that is sort of the problem I am having. The .profile for the user that I need to source is not just NAME=VALUE pairs, but it has logic in it to set vars under certain circumstances. It even has calls to other programs that it sources, so it has to be run as '. .profile' would do it.

      Yeah, a dumb design, but that's what I have to work with. I didn't do it, but I'm now stuck with it.

Re: sourcing a shell script/.profile and importing into %ENV
by Thelonius (Priest) on Mar 21, 2003 at 19:56 UTC
    You should be able to do:
    my $shell = $ENV{SHELL} || '/bin/sh'; # or maybe get user's shell fro +m /etc/passwd my $home = whatever ... my $envstr = qx($shell -c '. $home/.profile; env'); # some error checking should go on here my %NEWENV = map { split /=/, $_, 2 } split /\n/, $envstr;
    or something like that.
Re: sourcing a shell script/.profile and importing into %ENV
by hardburn (Abbot) on Mar 21, 2003 at 17:23 UTC

    I think a system("/bin/sh $ENV{HOME}/.profile") should do it.

    Reinvent a rounder wheel.

    Note: All code is untested, unless otherwise stated

      That won't work. The shell it runs processes the .profile file and promptly exits. The environment variables aren't passed back to the parent process.

      One thing the original poster might try is executing another Perl script through a login shell. The shell would process the .profile file and set the environment variables. The second Perl script would run in the context of the user.

      Instead of messing with $>, it would also be possible to use su to change the user. The following command will change to the user, use a login shell, and pass the command to it. As with any call to the shell, any variables need to be checked and escaped. Using the array form of system() might be a good idea.

      system("su -l -c ' $args' $user");
        Yes, an su would work, but the perl script has to do work as the user, not simply run a shell script as the user. I really don't want to have a script run a script which in turn runs a script which...........

        You are correct about the system call, it spawns a subshell and though I could source a .profile in that shell it would not be avaliable to me in the calling process. You also cannot qx/'. /opt/home/.profile'/ since '.' is a shell builtin, not a binary program to run.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://244933]
Approved by dga
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2018-01-22 22:36 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (238 votes). Check out past polls.