"Sourcing" a script's env into D?

Nick Sabalausky a at a.a
Thu Sep 29 13:56:36 PDT 2011


"Steven Schveighoffer" <schveiguy at yahoo.com> wrote in message 
news:op.v2k6axvveav7ka at localhost.localdomain...
> On Thu, 29 Sep 2011 13:31:13 -0400, Nick Sabalausky <a at a.a> wrote:
>
>> Due to process separation, the following won't work:
>>
>> script.sh:
>> #!/bin/sh
>> SOME_VAR=foobar
>>
>> test.d:
>> import std.process;
>> void main()
>> {
>>     system("./script.sh");
>>     assert(environment["SOME_VAR"] == "foobar");
>> }
>>
>> This, of course, is because the script is run in a totally separate 
>> process
>> (AIUI). The same thing happens in Windows, too.
>>
>> Is there some way to actually get the env that results from the script? 
>> I'm
>> looking for solutions for both Posix and Windows.
>
> No.  The way it works when you "source" a script from another script is it 
> uses the same process to interpret the script file, which sets the 
> environment up.
>

Right, that's why I wasn't surpeised about the above not working and put 
"Sourcing" in quotes. I was just wondering if there was some way to get the 
environment from the end of that process into the current process.

> Since a D program cannot interpret shell script, all you can do is read 
> the environment from the script (have it output the environment) and read 
> it in:
>
> #!/bin/sh
> SOME_VAR=foobar
> # note this is needed for SOME_VAR to get into the environment
>
> export SOME_VAR
>
> # write all environment variables to the output
> env
>
> test.d:
> import std.process:
> void main()
> {
>    processEnv(system("./script.sh")); // need to write the processEnv 
> function which processes the output from env.
> }
>

Good idea, that could work.

> I don't know what your real test case looks like, so I can't really 
> comment on the approach.  If it's simply loading file-defined environment 
> variables, there are better ways (as I'm sure you're aware).
>

Yea, I'm not even sure what approach I'll end up taking. Hell, I'm probably 
over-engineering it all anyway. FWIW, the scenario is like this:

I was making a shell script for one of my open source projects to help 
automate doing releases. The script is supposed to connect to a file server 
(generally via sshfs, which is freaking awesome, btw), update some stuff, 
and disconnect.

I figured there was no reason not to make the script public, but also that 
it would make sence for various reasons to make the connect/disconnect 
configurable (and not included). So the way I did it was it to have the 
script call the optional (and user-written) serverConnect and 
serverDisconnect scripts. The script also needed to know the path to the 
specific destination in the server, so I had the serverConnect set that path 
as an environment var (or the user could just set the env var elsewhere, 
wherever/however they wanted). So my script just sources the serverConnect 
script:

http://www.dsource.org/projects/goldie/browser/trunk/updateServerDocs?rev=449

Then I decided to convert the script to D (partly because my script-fu isn't 
all that great). Obviously now the env var solution won't work anymore, at 
least not quite as easily, so I'm thinking about what to do.

I was about to just change it from an env var to a cmd line param, but I'm 
thinking now my whole connect/disconnect system (proud of it as I was) is 
totally backwards and over-engineered.  I should just assume the computer's 
already connected, take the target path as a cmd line param, and let the 
user just wrap the whole damn thing in one "connect, run the tool, 
disconnect" script however they wish. That seems to make the most sense.









More information about the Digitalmars-d-learn mailing list