Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[9fans] environment variables

8 views
Skip to first unread message

Rudolf Sykora

unread,
Nov 23, 2009, 5:32:11 PM11/23/09
to
Hello,

If I have an rc script and I don't specify any rfork in it, then the namespace and the environment should be shared.
So, having an 'a' script

#!/bin/rc
a = hello
cd c   #later on...

and a 'b' script:

#!/bin/rc
a
echo $a

and running the 'b' script, I'd expect that the 'a' variable would be set to 'hello' and written out. But it does not work like that, thanks to some caching or what. How should the 'b' script, or whatever, be corrected so that it work?

Further, I am now a bit puzzled about whose property the 'current directory' is. Why isn't the directory changed to 'c' after runing either the 'a' or 'b' script? Is this always a local property of each shell?

Thank you a lot
Ruda

sqweek

unread,
Nov 23, 2009, 9:37:57 PM11/23/09
to
2009/11/24 Rudolf Sykora <rudolf...@gmail.com>:

> If I have an rc script and I don't specify any rfork in it, then the
> namespace and the environment should be shared.
<snip>

> But it does not work like that, thanks to some
> caching or what. How should the 'b' script, or whatever, be corrected so
> that it work?

Rc forks a new process for every [non builtin] command it runs. To
avoid such, use the . command to source the script instead of running
it.

> Further, I am now a bit puzzled about whose property the 'current directory'
> is. Why isn't the directory changed to 'c' after runing either the 'a' or
> 'b' script? Is this always a local property of each shell?

Each process has a current dir. I don't think it is ever shared between them.
-sqweek

Rudolf Sykora

unread,
Nov 24, 2009, 3:40:29 AM11/24/09
to
 Rc forks a new process for every [non builtin] command it runs. To
avoid such, use the . command to source the script instead of running
it.
Ok. The thing about forking is clear. Yes, your suggestion of using . would 'solve' the problem of seeing the variables set in the 'a' script (called from 'b'). However then I would e.g. really have to care about individual 'cd' commands in the 'a' script so as to know where I am after returning back to the 'b' script. I thought there would be some way to make the 'b' script reread the environment (i.e. to achieve information passing through the environment). What is the use of that 'caching' that hinders this way?  

 Each process has a current dir. I don't think it is ever shared between them.
-sqweek

Ok. I was tired...

Thanks
Ruda

roger peppe

unread,
Nov 24, 2009, 6:33:56 AM11/24/09
to
2009/11/23 Rudolf Sykora <rudolf...@gmail.com>:

> Hello,
>
> If I have an rc script and I don't specify any rfork in it, then the
> namespace and the environment should be shared.
> So, having an 'a' script
>
> #!/bin/rc
> a = hello
> cd c   #later on...
>
> and a 'b' script:
>
> #!/bin/rc
> a
> echo $a
>
> and running the 'b' script, I'd expect that the 'a' variable would be set to
> 'hello' and written out. But it does not work like that, thanks to some
> caching or what. How should the 'b' script, or whatever, be corrected so
> that it work?

yes, rc caches the values of its environment variables
to avoid reading all the values after every command is run.

if you want to re-get the value of an environment variable,
you can do:

ifs=() var=`{cat /env/var}

> Further, I am now a bit puzzled about whose property the 'current directory'
> is. Why isn't the directory changed to 'c' after runing either the 'a' or
> 'b' script? Is this always a local property of each shell?

in plan 9 the current working directory is per-process
(inferno is different here - it's part of the current name space).

Rudolf Sykora

unread,
Nov 24, 2009, 11:32:11 AM11/24/09
to
if you want to re-get the value of an environment variable,
you can do:

ifs=() var=`{cat /env/var}

Ok. So if one wants to update the rc's view of the environment, one must write sth. along the lines

for(var in `{ls /env}) {
    ifs=() contents = `{cat /env/$var}
    if (~ $var *#*) fn `{echo $var | awk '{split($0, a, "#"); print a[1]}'} {$contents}
    if not var = $contents
}

?

Thanks
Ruda

erik quanstrom

unread,
Nov 24, 2009, 1:24:11 PM11/24/09
to
> for(var in `{ls /env}) {
> ifs=() contents = `{cat /env/$var}
> if (~ $var *#*) fn `{echo $var | awk '{split($0, a, "#"); print a[1]}'}
> {$contents}
> if not var = $contents
> }

pretty sure that's a syntax error. and for simple variables, quite
wrong. this function does better, but still screws up a few things.

v=() for(v in `{cd /env; ls -Q}){
if(~ $v *'#'*)
. /env/$v
if not x=() if(! ~ $v pid status '*' ifs){
# f015; plan 9 raw alt
ifs=() eval $v '= (' `{tr '\00' '' < /env/$v >/tmp/fubar ;
echo ' ,s:'':'''':g
,s::'' '':g
,s:(\n|[^])+:''&'':g
,s:: :g
,p' |
sam -d /tmp/fubar >[2=]
} ')'
}
}

the easy (and correct) answer is
exec rc

- erik

Rudolf Sykora

unread,
Nov 24, 2009, 1:41:03 PM11/24/09
to
the easy (and correct) answer is
       exec rc

- erik

Well but this you can't do when being in the middle of a script execution...
Can you?

Thanks
Ruda

roger peppe

unread,
Nov 25, 2009, 6:51:52 AM11/25/09
to
generally, the correct answer is: don't do that.
it's better to treat subshells as if they exist
in a different scope, even if the environment
group isn't forked.

if you want to get values back from a script,
send them in its stdout.

2009/11/24 Rudolf Sykora <rudolf...@gmail.com>:

0 new messages