Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the Terminal's $PATH variable from within my mac app, it seems to uses a different $PATH

I'm trying to make a mac app where the user can type in commands just like they would in the mac terminal, I got most of it working however I found out that the $PATH variable of apps run from the finder or xcode is different than the $PATH variable the Terminal uses.

I can run commands and also found a way to add a predefined path to the application's $PATH variable but I need a way to automatically read the Terminal's $PATH variable and copy it to the Application's $PATH variable. This should be automated as users will have different path's inside their variable.

I also found out that when I run the application from the terminal with "open appname.app" the correct $PATH variable is used (the same one the terminal uses)

This is my code so far:

    let task = Process()
    var env = ProcessInfo.processInfo.environment
    var path = env["PATH"]! as String
    path = "/usr/local/bin:" + path
    env["PATH"] = path
    task.environment = env
    task.launchPath = "/usr/bin/env"
    task.arguments = ["echo","$PATH"]
    let pipe = Pipe()
    task.standardOutput = pipe
    task.standardError = pipe
    task.launch()
    task.waitUntilExit()
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
    print(output)

This will add "/usr/local/bin" to the Application's $PATH but I need a way to copy the values from the Terminal's $PATH.

Thanks!

like image 374
Steven B. Avatar asked Jan 08 '17 17:01

Steven B.


People also ask

How do I find the PATH environment variable in Mac?

You need to use the command echo $PATH to display the PATH variable or you can just execute set or env to display all of your environment variables. By typing $PATH you tried to run your PATH variable contents as a command name.

How do I open an environment variable on a Mac?

This is very easy. Just open the Terminal and run the command printenv as shown below. This will list all the environment variables currently set.

What is the default PATH variable for Mac?

Ideally, the shell config or profile files comprise the following as the default PATH variable in Mac: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin, to allow you to execute various programs or commands in the terminal without specifying their absolute paths. 3. How do I fix my PATH environment variable?

How do I add an app to the PATH variable?

ifconfig - with PATH variable assigned. Adding the app path to the PATH variable. All we need to do is create a new hidden file called: .bash_profile in your user home. so open up a terminal and type the following. Inside the .bash_profile file you want to type something like this it will be different depending on what you want to do.

What does it mean to permanently change path on Mac?

Setting the PATH on Mac permanently means your PATH environment variable changes aren’t limited to your current shell session, unlike the temporary variable settings. So your system’s shell can continue to access it even when you start a new session or restart your Mac.

How do I set a program’s path on a Mac?

In case you want to use a program regularly, you must set its path permanently. To do this, you need to access the shell’s configuration or profile file and add the program’s path to it. Depending on the macOS version you’re running on your Mac, this can be done via either the bash shell or zsh (z shell).


1 Answers

Adding bash Shell Path

The default shell paths can be found in /etc/paths and /etc/path.d/. One way to read the shell paths is to use the path_helper command. Extending the code example above and using bash as the shell:

let taskShell = Process()
var envShell = ProcessInfo.processInfo.environment
taskShell.launchPath = "/usr/bin/env"
taskShell.arguments = ["/bin/bash","-c","eval $(/usr/libexec/path_helper -s) ; echo $PATH"]
let pipeShell = Pipe()
taskShell.standardOutput = pipeShell
taskShell.standardError = pipeShell
taskShell.launch()
taskShell.waitUntilExit()
let dataShell = pipeShell.fileHandleForReading.readDataToEndOfFile()
var outputShell: String = NSString(data: dataShell, encoding: String.Encoding.utf8.rawValue) as! String
outputShell = outputShell.replacingOccurrences(of: "\n", with: "", options: .literal, range: nil)
print(outputShell)

let task = Process()
var env = ProcessInfo.processInfo.environment
var path = env["PATH"]! as String
path = outputShell + ":" + path
env["PATH"] = path
task.environment = env
task.launchPath = "/usr/bin/env"
task.arguments = ["/bin/bash", "-c", "echo $PATH"]
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
var output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
output = output.replacingOccurrences(of: "\n", with: "", options: .literal, range: nil)
print(output)

Note:

  1. This code example calls the shell in non-interactive mode. This means that it won't execute any user specific profiles; such as /Users/*userid*/.bash_profile.
  2. The paths can be listed multiple times in the PATH environment variable. They will be traversed from left to right.

References

There are a couple of threads on application and shell PATH's for OS X which provide more context How to set system wide environment variables on OS X Mavericks and Setting the system wide path environment variable in mavericks

like image 94
Graeme Avatar answered Nov 15 '22 04:11

Graeme