[comp.unix.wizards] Set parent env with csh script

mvp@v7fs1.UUCP (Mike Van Pelt) (01/08/89)

I asked comp.unix.questions, but got only blank stares.  So,
maybe this is a wizardly type question...

I would like to write a shell script (csh preferred) that will
set a few environment variables to various things.  Of course,
just doing   setenv foo bar  in the script only works for that
subshell and its children, not for the calling shell.  I've
gone back and forth through all the likely places in the manuals,
and haven't found any mention of this.

Is it possible for a subshell to changes the calling shell's 
environment?  How?
-- 
I would like to electrocute everyone who uses the    | Mike Van Pelt
word 'fair' in connection with income tax policies.  | Video 7                 
           -- William F. Buckley                     | ...ames!vsi1!v7fs1!mvp

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/08/89)

In article <174@v7fs1.UUCP> mvp@v7fs1.UUCP (Mike Van Pelt) writes:
>I would like to write a shell script (csh preferred) that will
>set a few environment variables to various things.  Of course,
>just doing   setenv foo bar  in the script only works for that
>subshell and its children, not for the calling shell.  I've
>gone back and forth through all the likely places in the manuals,
>and haven't found any mention of this.

It's implicit in the description of how environment variables work.

>Is it possible for a subshell to changes the calling shell's 
>environment?  How?

There is no official way for a subprocess to alter an ancestor
process's environment.  Specialized ways can be devised.  In
your case, however, probably all you need is to realize that
SOURCING a shell script (as opposed to EXECUTING it) causes the
changes to occur in the invoking shell context (as opposed to
a subprocess context).  Thus you can alter environment variable
via a sourced script that does setenv (or Bourne shell equivalent).

chris@mimsy.UUCP (Chris Torek) (01/08/89)

In article <174@v7fs1.UUCP> mvp@v7fs1.UUCP (Mike Van Pelt) writes:
>Is it possible for a subshell to changes the calling shell's environment?

Yes.

>How?

By getting the cooperation of the calling shell.  For instance:

	#! /bin/sh
	# edit environment variable
	case $# in 1);; *) echo "usage: edit-env varname" 1>&2; exit 1;; esac
	TF=${TMPDIR-/tmp}/edenv$$
	rm -f $TF
	trap 'rm -f $TF; exit 1' 1 2 3 15
	trap 'rm -f $TF; exit' 0
	eval echo "$1" > $TF
	if ${EDITOR-vi} $TF </dev/tty >/dev/tty 2>&1; then
		echo "setenv $1 `cat $TF`"	# csh-specific
	fi

Then:

	% alias edit-env 'eval `~/bin/edit-env`'
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

wnp@dcs.UUCP (Wolf N. Paul) (01/08/89)

In article <174@v7fs1.UUCP> mvp@v7fs1.UUCP (Mike Van Pelt) writes:
>I would like to write a shell script (csh preferred) that will
>set a few environment variables to various things.  Of course,
>just doing   setenv foo bar  in the script only works for that
>subshell and its children, not for the calling shell.  I've
>gone back and forth through all the likely places in the manuals,
>and haven't found any mention of this.
>
>Is it possible for a subshell to changes the calling shell's 
>environment?  How?

No, it is not possible for a process to change its parent's 
environment.

But what you propose can be accomplished by running the shell
script via "source" (under csh) or "." (under sh or ksh).
Thus, you can put your "setenv" statements into a script, and
then call the script like this:

% source scriptname

or

$ . scriptname

If you don't want to remember this special invocation, create
an alias (under csh, alias scriptname "source scriptname"),
or a shell function (under sh or ksh) to call it.
-- 
Wolf N. Paul * 3387 Sam Rayburn Run * Carrollton TX 75007 * (214) 306-9101
UUCP:     killer!dcs!wnp                 ESL: 62832882
DOMAIN:   dcs!wnp@killer.dallas.tx.us    TLX: 910-380-0585 EES PLANO UD

sasc03@dsachg1.UUCP (Ned D Hanks) (01/09/89)

From article <174@v7fs1.UUCP>, by mvp@v7fs1.UUCP (Mike Van Pelt):
> I asked comp.unix.questions, but got only blank stares.  So,
> maybe this is a wizardly type question...
  ...
> Is it possible for a subshell to changes the calling shell's 
> environment?  How?

No.  The enviroment of the child shell is a copy of the parents and goes
away when the shell exits.

 _ __              __      _    ,
' )  )      /     /  )    ' )  /            /
 /  / _  __/     /  /      /--/ __.  ____  /_  _
/  (_</_(_/_    /__/_     /  (_(_/|_/ / <_/ <_/_)_


-- 
...!uunet!unbc3!haven!ames!lll-tis!oodis01!obie!wsccs!ned
...!uunet!unbc3!haven!ames!lll-tis!oodis01!dsachg1!nhanks

daniel@island.uu.net (Dan "yes that is my real name" Smith) (01/10/89)

In article <174@v7fs1.UUCP> mvp@v7fs1.UUCP (Mike Van Pelt) writes:
>I would like to write a shell script (csh preferred) that will
>set a few environment variables to various things.  Of course,
>just doing   setenv foo bar  in the script only works for that
>subshell and its children, not for the calling shell.

	Source the script instead of running it.  That way, any environment
variables (and csh variables) that the script changes will be seen
in the shell you "sourced" from.

				dan
-- 
    /na/usa/ca/marin/SanRafael/94903/4000CivicCtrDr/IslandGraphics/DanSmith
 daniel@island.uu.net  unicom!daniel@pacbell.com  {lll-crg,apple}!well!dansmith
 ph: +1 415 332 FAST(h) 491 1000(w) 491 0402(Fax)  d: Island's coffee is laced
    my mind likes unix, my hands guitar, my stomach pizza, and my feet skis

guy@auspex.UUCP (Guy Harris) (01/10/89)

>Is it possible for a subshell to changes the calling shell's 
>environment?

Only if you can convince the calling shell to somehow take requests that
it change its environment from the subshell (there are no built-in
mechanisms in the C shell for this, so you'd have to play games with
some script reading input from the child shell and using "eval" or
somesuch to set its environment.  UNIX processes do not have the ability
to modify their parent shell's environment (in the UNIX sense of
"environment").

If your script just sets some environment variables, you might want to
consider running it with the "source" command (C shell) or the "."
command (Bourne/Korn shell); this causes the commands in the script to
be executed in the *same* process, rather than in a child process.  You
might be able to use aliases to syntactically sugar-coat this, if
desired....

ckl@uwbln.UUCP (Christoph Kuenkel) (01/10/89)

In article <9314@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:

> [...]
> SOURCING a shell script (as opposed to EXECUTING it) causes the
> changes to occur in the invoking shell context (as opposed to
> a subprocess context).  Thus you can alter environment variable
> via a sourced script that does setenv (or Bourne shell equivalent).

Unfortunately, csh doesn't get it right since it does not evaluate $path
to lookup the file to be sourced (at least on my SysV based system).
Therefore, the location of the script is not transparent to the user as it
is in the case of an executed shell script.  
Bourne shell does it right, but attention, in

	while <expr>; do
		<stmnt>
	done <io redirection>

<stmnt> is executed in a ``subrocess context'' due to the io redirection!
So any variable assignement and/or environment setting is uneffective outside
the while-loop.
Any elegant solution to that?

christoph
-- 
# include <std/disclaimer.h>
Christoph Kuenkel/UniWare GmbH       Kantstr. 152, 1000 Berlin 12, West Germany
ck@tub.BITNET                ckl@uwbln             {unido,tmpmbx,tub}!uwbln!ckl

jiii@visdc.UUCP (John E Van Deusen III) (01/10/89)

You write:

> I would like to write a shell script (csh preferred) that will
> set a few environment variables to various things.
  
Suppose you have a file named envtest containing the following:

export TEST TEST1
TEST=xxx
TEST1="aaa bbb"

If envtest is executable, then preceding the name with a ". "
will execute envtest in the same shell.  For example:
$ . envtest

The shell command
$ eval `cat envtest`
will also put TEST=xxx and TEST1=aaa bbb into your environment.

The env(1) command lets you modify the environment.  If the file
envtest contained

TEST=xxx

then the command
$ exec env - `cat envtest` sh
will leave you in a shell where only TEST=xxx is in the environment.
Note that env(1) only wants arguments of the form name=value.  On my
system TEST1="aaa bbb" will not work with env, because it reevaluates
its arguments.

> Is it possible for a subshell to change the calling shell's 
> environment?  How?

You can use getenv(3C) from a C program to return the address of an
environment variable of the form name=value.  You can modify what is
stored at that location, but not with impunity.  If you set
TEST=xxxxxxxxxx
prior to invoking your program, then you can change its value to
be anything up to 10 characters long (plus a terminating null).  The
important thing is that the storage for TEST has to be allocated
prior to the execution of your program.
--
John E Van Deusen III, PO Box 9283, Boise, ID  83707, (208) 343-1865

guy@auspex.UUCP (Guy Harris) (01/11/89)

 >> Is it possible for a subshell to change the calling shell's 
 >> environment?  How?
 >
 >You can use getenv(3C) from a C program to return the address of an
 >environment variable of the form name=value.  You can modify what is
 >stored at that location, but not with impunity.

This won't do anything about the copy of that environment variable (if
any) in the *parent* process of the process in which it's done, which is
what the guy wanted.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/11/89)

In article <1291@uwbull.uwbln.UUCP> ckl@uwbln.UUCP (Christoph Kuenkel) writes:
>So any variable assignement and/or environment setting is uneffective outside
>the while-loop.
>Any elegant solution to that?

Well, I think we already solved the original problem, but as for the case
you bring up, various workarounds are sometimes possible, depending on
just what it is you really need to do.  Often, one can construct a string
in the (non-subprocessed!) loop then use the string with "exec" or some
such afterwards.

lml@cbnews.ATT.COM (L. Mark Larsen) (01/11/89)

In article <1291@uwbull.uwbln.UUCP> ckl@uwbln.UUCP (Christoph Kuenkel) writes:
# ...Bourne shell does it right, but attention, in
# 
# 	while <expr>; do
# 		<stmnt>
# 	done <io redirection>
# 
# <stmnt> is executed in a ``subrocess context'' due to the io redirection!
# So any variable assignement and/or environment setting is uneffective outside
# the while-loop.
# Any elegant solution to that?
# 
# christoph

By putting the loop into a function and redirecting at the function call, the
variables set in the function will still be in effect outside of the while
loop.  For example:

func ()
{
	while <expr>; do
		<stmnt>
	done
}
func <io redirection>

This works with sh.  Incidently, ksh does not share the "feature" of sh that
force while and for loops to be executed in a subprocess, so this kind of 
trick is not necessary.

Elegant?  You decide.

L. Mark Larsen
lml@atlas.att.com
att!atlas!lml

hwt@bnr-public.uucp (Henry Troup) (01/11/89)

Time to add this to the 'Most Frequently Asked Questions'?
utgpu!bnr-vpa!bnr-fos!hwt%bnr-public | BNR is not 	| All that evil requires
hwt@bnr (BITNET/NETNORTH) 	     | responsible for 	| is that good men do
(613) 765-2337 (Voice)		     | my opinions	| nothing.

childers@avsd.UUCP (Richard Childers) (01/13/89)

In article <174@v7fs1.UUCP> mvp@v7fs1.UUCP (Mike Van Pelt) writes:

>Is it possible for a subshell to changes the calling shell's 
>environment?  How?

I don't think it's possible for this to happen.

Your subject line suggests that you've done a fair amount of browsing. Thus,
you know what the terms 'parent' and 'child' refer to.

As far as I know, while a 'child' can inherit a 'parent' environment, there
is no official path for doing the opposite.

There may well be an unofficial path, something involving breaking through
the protections imposed by UNIX ... but it would be much simpler to make an
alias, seeing as you're working with a csh, wouldn't it ?

>I would like to electrocute everyone who uses the    | Mike Van Pelt
>word 'fair' in connection with income tax policies.  | Video 7                 
>           -- William F. Buckley                     | ...ames!vsi1!v7fs1!mvp

-- richard

-- 
 *             "I haven't lost my mind ... it's backed up on tape."           *
 *                            ( Pete Da Silva )                               *
 *      ..{amdahl|decwrl|octopus|pyramid|ucbvax}!avsd.UUCP!childers@tycho     *
 *          AMPEX Corporation - Audio-Visual Systems Division, R & D          *

rbj@nav.icst.nbs.gov (Nilbert T Bignum) (02/14/89)

I'm surprised no one has mentioned ioctl(0,TIOCSTI,...).
You can change the parent's directory that way too.

Maybe no one mentioned it because it is `not recommended'.
I don't recommend it either, but mention it for completeness.

	Nilbert T Bignum <rbj@nav.icst.nbs.gov>
	NTSI: Never Twice the Same Institute