1

I have a program that does a LOT of env manipulation. It sets PYTHONPATH and LD_LIBRARY_PATH and stuff like that.

This program needs to run ANOTHER program, but in a fresh env, without all of the env manipulation, but WITH the base env from rc files.

I thought I'd be able to do this with csh -c but that keeps the current env. Is there a good way to do this?

It doesn't really matter what shell I use for this. Also note that I need the original .rc files, so env -i doesn't quite work for me. (I suppose I could hack something together with env and bash -cl, but there should be a nicer method)

5 Answers5

2

Forking a new process will preserve the environment.

If you need to run a process with a given environment all processes started by this one will use this environment, too.

However you could save an unpolluted environment into a file: export >original_env.

Later you could clear the polluted environment using env -i and import the old environment by sourcing that file.

michas
  • 21,510
  • I'd really rather not have to save the env, wipe, reset to default env, wipe, and then reset to saved env. that takes too long. – Brian Postow Nov 13 '13 at 20:19
  • In this case you are probably out of luck. If your override a variable and do not save the original value you have no way to set it back to that value later. (And if I understand you correctly you need the old value later.) – michas Nov 13 '13 at 20:26
  • However it is not as complicated as you think. You only have to save the fresh environment once. Afterwards you simply have to source it whenever you need the fresh environment. (This should be no performance issue at all.) – michas Nov 13 '13 at 20:29
1

I'm not sure that this is optimal, but I have gotten the following to work in small tests:

env -i /bin/bash -cl 'COMMAND'

Evidently, you can't run csh with -cl because -l can't coexist with any other arguments... but in bash you can.

ETA:

I think this is what I'm going to actually use:

#!/bin/csh -f
set evs = ""
if ($1 == '--envVars') then
    set envs = "$2"
    shift
    shift
endif

env -i $envs CMD="$*" /bin/bash -c '$CMD'

It lets me input ENV variables from the command line if I need to, like $PATH and $PYTHONPATH...

0

The easiest way I can think of is to not export your variables. Depending on your use scenario, this may or may not be feasible. For example:

$ cat a.sh
#!/bin/bash
BAR=foo
export BAZ=foo
bash -c 'echo "bash -c : BAR: $BAR, BAZ: $BAZ"'
echo "normal  : BAR: $BAR, BAZ: $BAZ"

$ ./a.sh
bash -c : BAR: , BAZ: foo
normal  : BAR: foo, BAZ: foo

As you can see in the example above, the shell ;aunched by bash -c will only have access to exported variables.

terdon
  • 242,166
  • No, I need to export the variables because the top level program is actually several programs that call each other. – Brian Postow Nov 12 '13 at 14:56
  • @BrianPostow yeah, I was afraid of that. Is running `ssh localhost COMMAND" an option? – terdon Nov 12 '13 at 14:57
  • No, because ssh will revert the pwd to ~ which may mess other things up. Also, that requires either the user to type in the password, or an rhosts to be set up, and neither of those work for this setting. – Brian Postow Nov 12 '13 at 15:03
0

Depending on what you want,

env -i PATH="$(getconf PATH)" HOME="$HOME" USER="$USER" SHELL="$SHELL" "$SHELL" -lc "your command"

would try to reset a default environment for your shell. You can also add an i to the shell options so that it is interactive.

Alternatively you can do

env > saved.env
...
env -i `cat saved.env` your command

to save and restore the environment. But you'll have to process saved.env so that it is properly quoted (I've some env vars with spaces and tabs in their value).

AProgrammer
  • 2,318
0

The only way I found is to use sudo, if you're allowed to do that:

sudo -u "$USER" path_to_script

Example script:

#!/bin/sh
set | grep ARGH

Usage:

$ export ARGH=yes
$ sudo -u "$USER" ./check_env
(empty line, so ARGH is not set)
roo
  • 1