3

I found the idiomatic answer for getting an environment variable, which I might generalize as:

NSString *key = @"<whatever>";
NSString *result;
result = [[[NSProcessInfo processInfo]environment]objectForKey:key];

But what's the idiomatic way for setting an environment variable? I see from the docs that the environment dictionary is a read-only NSDictionary object, rather than an NSMutableDictionary, or some other special class that would allow me to do a setObject:forKey:. (And indeed, if I coerce the types this way, it has no visible effect.)

I could use the standard UNIX (*nix) way:

char *key = "<whatever>", *value = "<something>";
int overwrite = 1;
setenv(key, value, overwrite);

And if that's what I need to do, that's what I'll do. I'm just wondering, is there an idiomatic objective-C way of doing this, that's different, and that I'm just failing to find? I like to do things in recommended ways where I can, which seems to me it would mean using an Objective-C class... if there is one for doing this. How do others do this?

(For what it's worth, my next step will be to then execute a program with the modified environment.)

Community
  • 1
  • 1
lindes-hw
  • 939
  • 8
  • 11
  • If you're just modifying the environment for the benefit of a subprocess, you can use `NSTask`, which has an `environment` property which determines the environment the subprocess will inherit. Other than that, yes, `setenv()` is the way to modify the current process's environment. – Ken Thomases Nov 26 '14 at 01:06
  • Well, that's what I just figured out on my own, too... cool, thank you, @KenThomases! – lindes-hw Nov 26 '14 at 01:24

1 Answers1

0

Ahh, but of course. I wish I'd looked up the idiomatic way to launch a process first, as that had my answer. Using NSTask, I gain access to a setEnvironment: method. So, what's working for me is something like this:

NSTask *myTask = [[NSTask alloc] init];
myTask.launchPath = @"/path/to/something";

NSMutableDictionary *env = [[NSMutableDictionary alloc] init];

// optionally copy in existing environment first:
// (we could also copy values for a limited set of specific keys, if we wanted.)
[env addEntriesFromDictionary:[[NSProcessInfo processInfo] environment]];
// then add anything else we might want:
[env setObject:@"test value" forKey:@"TEST_VAR"];
// and maybe delete things we don't want:
[env removeObjectForKey:@"UNWANTED_VAR"];

// now set the task up to use this newly-built environment:
[myTask setEnvironment:env];
// and run it in whatever way makes sense:
[myTask launch];
[myTask waitUntilExit];

From there, we run our program with a modified environment.

I still don't know if/how I can alter the environment of the running process in an idiomatic way, so if someone has that answer, I'd like to hear about it, but for my main purposes, this will suffice.

lindes-hw
  • 939
  • 8
  • 11