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!
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.
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.
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?
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.
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.
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).
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:
/Users/*userid*/.bash_profile
.PATH
environment variable. They will be traversed from left to right.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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With