NSTask not picking up $PATH from the user's environment

Related searches

I don't know why this method returns a blank string:

- (NSString *)installedGitLocation {
    NSString *launchPath = @"/usr/bin/which";

    // Set up the task
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:launchPath];
    NSArray *args = [NSArray arrayWithObject:@"git"];
    [task setArguments:args];

    // Set the output pipe.
    NSPipe *outPipe = [[NSPipe alloc] init];
    [task setStandardOutput:outPipe];

    [task launch];

    NSData *data = [[outPipe fileHandleForReading] readDataToEndOfFile];
    NSString *path = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

    return path;
}

If instead of passing @"git" as the argument, I pass @"which" I get /usr/bin/which returned as expected. So at least the principle works.

from the terminal

$ which which
$ /usr/bin/which
$
$ which git
$ /usr/local/git/bin/git

So it works there.

The only thing I can think of is that which isn't searching through all the paths in my environment.

This is driving me crazy! Does anyone have any ideas?

EDIT: It looks like this is about setting up either NSTask or the user's shell (e.g., ~/.bashrc) so that the correct environment ($PATH) is seen by NSTask.

Running a task via NSTask uses fork() and exec() to actually run the task. The user's interactive shell isn't involved at all. Since $PATH is (by and large) a shell concept, it doesn't apply when you're talking about running processes in some other fashion.

NSTask not picking up $PATH from the user's environment, NSTask not picking up $PATH from the user's environment. Question. I don't know why this method returns a blank string: - (NSString *)installedGitLocation� GUI programs do not inherit variables from ~/.bash_profile, ~/.bashrc or other shell init files. TeX Live Utility allows the user to add TeX binaries to its internal (i.e., in-memory) PATH variable by means of a preference setting. Other programs may do via shell scripts, config files in the home directory, or other configuration mechanisms.

Try,

    [task setLaunchPath:@"/bin/bash"];
    NSArray *args = [NSArray arrayWithObjects:@"-l",
                     @"-c",
                     @"which git",
                     nil];
    [task setArguments: args];

This worked for me on Snow Leopard; I haven't tested on any other system. The -l (lowercase L) tells bash to "act as if it had been invoked as a login shell", and in the process it picked up my normal $PATH. This did not work for me if the launch path was set to /bit/sh, even with -l.

NSTask Tutorial for OS X, In this OS X NSTask tutorial, learn how to execute another program on Make sure you use the parent directory of a project, not the .xcodeproj file itself. is necessary as Xcode won't pick up on the file's permissions change,� Workflows do not use a proxy because neither OS X nor Alfred propagates proxy settings to the standard http_proxy environmental variable or otherwise provide that information in a usable manner. If your machine can only connect to the web via a proxy server, workflows will not work unless the author has taken steps to ensure it does work. Which

Is /usr/local/git/bin in your $PATH when you run the program? I think which only looks in the user's $PATH.

Mac OS X Programming Secrets, If there's no file by that name, you get the disheartening message Command not found. You can create an NSTask object in your application and use it to control a shell After setting up the launch path, we call setArguments to say what should be passed to If you want to join us in picking the game back up, we've put. It seems to me that one of the main vulnerabilities could be eliminated by simply not passing the path of finish_installation to the XPC service. That stops it from being an arbitrary copying tool. Can't the service figure that out for itself (it should be a fixed relative path from the xpc service's own bundle location, as Andy mentioned in an

Take a look at the question Find out location of an executable file in Cocoa. It looks like the basic problem is the same. The answer unfortunately isn't nice and neat, but there's some useful info there.

NSTask class reference, Raises an NSInvalidArgumentException if the launch path is not set or if the subtask cannot be started for some reason (eg. the executable does not exist or the� This way we can reset the chached icons when it becomes stale while we've not been told (e.g. when the underlying file is renamed on disk). Also retain the cached icons and URLs, because it's not guaranteed that they're retained somewhere else.

In Swift NSTask is replaced by Process but this is what it works for me:

let process = Process()
process.launchPath = "/bin/bash"
process.arguments = ["-l", "-c", "which git"]

objective-c, Es solo despu�s de leer la pregunta de NSTask not picking up $PATH from the user's environment (el t�tulo de la pregunta fue enga�oso) y con estas dos� ASIHTTPRequest changelog v1.8.1 28th May 2011. v1.8.1 is a maintenance update that includes lots of bug fixes and several small new features. As ever, thanks to everyone who has contributed code, bug reports and feature requests!

This banner text can have markup.. web; books; video; audio; software; images; Toggle navigation

To explicitly search user only, we would pass a -e builtin psearch option to exclude searching the builtin namespace. This is a little counterintuitive, but it makes an odd sort of sense. The default search path for psearch is builtin and user, so if we specify a -s user, searching builtin and user would still be what we’re asking it to do.

Comments
  • I'm writing a CLI app, and I've found NSTask sees the $PATH when you run your program from the CLI. Unfortunately, you must compile and run on the command line as well, because testing the program in Xcode brings us to this situation.
  • More to the point, if the user sets his PATH using one of his shell's run-commands files, the app does not receive that variable because it wasn't run from the shell; as such, the subprocess doesn't inherit it because it's the process's direct child. (cont'd because SO limits length for some reason)
  • But if the user sets PATH in ~/.MacOSX/environment.plist, the application does receive the PATH variable, and the subprocess will inherit it.
  • In other words, the environment (where environments such as PATH are stored) used for executing applications is not the same as the environment used for executing shells (bash, etc.). Mac OS X maintains two separate environments - one for shells, one for applications.
  • That assumes that the user uses bash, or that they use another Bourne-like shell and they set PATH in their .profile. Anyone who uses tcsh and anyone who uses ksh, zsh, or fish and didn't set PATH in .profile (e.g., they set it in .zshenv instead) is screwed.
  • See this answer on another question, and my comment on it, for the full version of this solution: stackoverflow.com/questions/208897/… It's certainly not simple.
  • Thanks so much for this answer.
  • from logging NSProcessInfo in the method, my Path comes up as PATH = "/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"; which isn't my full shell path. How would I get the user's path so that I could set it in the environment?
  • I edited the question to reflect this issue. +1 for pointing toward the problem.
  • Since $PATH can be set in multiple places including ~/.profile ~/.bashrc etc, the easiest solution would probably be the technique outlined in Brian Webseter's link. Something like "/bin/bash -c env | grep ^PATH"