setenv within a program doesn't last
I wrote a C++ program which calls setenv() to change
the "path" environment variable. Within the program I can then call getenv("PATH") and see the new value. But after the program exits, if I list the environment variables using the tcsh command: setenv | grep -i path I see the old path, not the one newly set. Apparently the program is run with a copy of the environment, which is modified and then discarded. Any ideas how to make this program work? I want the path changed within the shell after the program terminates. Note: I am using the setenv() command described in section 3 of the man pages (man 3 setenv). I also tried system("setenv path=(/bin /sbin)"); but it failed the same way. Thanks, Mark Red Hat Linux version 9 gcc compiler tcsh shell used |
When you run a program, it runs in it's own separate sub-process.
When the sub-process exits, then all of the environment variables exit with it. You return to the parent process, which never saw those changes. If you want to set envrionment variables that stick around, you probably want to try using a simple script -- then execute the script with dot notation like this: Code:
. myscript.shl |
Hi, I think what you are trying to do willl not work (if I'm wrong I'd love to know the answer!). Since your program is creating a child process which is then used to create the variable using setenv, then when this process exits the enviroment change is lost, it's said much better here:
"A script can export variables only to child processes, that is, only to commands or processes which that particular script initiates. A script invoked from the command line cannot export variables back to the command line environment. Child processes cannot export variables back to the parent processes that spawned them." Advanced Bash Cripting Guide Ch 4.4 Cheers |
Quote:
What you could do to fix it is, instead of exiting your program, replacing it with a new shell process. For example: (C..., not C++. Sorry) : Code:
#include <unistd.h> Code:
/usr/bin/pstree | /bin/grep -B1 pstree Code:
exec ./my_program Hope this helps. |
P.S. If changing environment variables is the only thing your program does, stick with jim mcnamara's solution. Much easier and more apropriate for just changing env. vars.
|
You could just do this: system("VAR=setting; export VAR");
|
itsme - wont'work because system() forks (using exec) and creates a subprocess.
"export" only creates the variable for that process and any of it's children - not the parent process. If a child could alter parent environments by using export, unix would have zero security. |
Another way to handle this is to just have your program output shell commands to set the environment the way it wants it. e.g. ssh-agent is meant to be called like "eval `ssh-agent`"
The tricky part of this is that you need to output command appropriate to the shell you're using: csh and sh are a little different. You can check the SHELL environment variable of course. |
Thanks for all the replies.
It looks like my original plan is simply not possible. For closure, I finally used a method like that proposed by "aluser": eval `fixpath` (recall that I am using tcsh) where the name of my program is: fixpath and the program writes a string like this to stdout: set path=(/sbin /usr/bin) It is not as clean as I had hoped for, but not too ugly. Thanks 'aluser', for I didn't know about the eval command. Mark |
All times are GMT -5. The time now is 06:41 PM. |