简体   繁体   中英

Access user environment variable in Swift for macos

I'm developing console app for mac os in swift and i want to access user environment variables when calling bash command. I use the following code to run bash command in swift:

@discardableResult
func shell(_ command: String) -> String? {
    let task = Process()
    task.launchPath = "/usr/bin/env"
    task.arguments = ["bash", "-c", command]
    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: String.Encoding.utf8)

    return output
}

When i run /usr/bin/env in my terminal i see the desired variable but when i run shell("/usr/bin/env") in code i don't see one. The ProcessInfo.processInfo.environment["MY_ENV_VAR"] also don't show me the needed variable. How to access user defined env vars in swift?

I've been struggling with a very similar problem recently. While I don't have a perfect solution for you, I do have some suggestions.

First, it really matters where exactly MY_ENV_VAR has been defined. If it is inside of a .bashrc file, you'll need to start up bash in interactive mode with -i so it reads that file. If it is defined in .bash_profile , you'll need use -l to start a so-called login shell.

In my particular case, I have to use both -i and -l to see the env vars I'm after. This all gets even more complex if the user doesn't use bash. I use fish, for example, so my required ENV variables aren't visible to bash at all, regardless of the bash invocation.

So, what I actually do is first determine what shell is being used, and then invoke that shell with -i -l -c . zsh, bash and fish all support these options.

It's a real pain, and I'm not even sure that method is reliable. But, it is working for me across a number of different user environments.

ProcessInfo.processInfo.environment

Will give you the environment variables for the user which launch the app but Xcode don't launch the app with your rights and environment.

So for the testing phase you can define the needed variable in Xcode like the photo below

在此处输入图片说明

If you want to be sure, write the following code in a file (ei: "main.swift"):

import Foundation

print(ProcessInfo.processInfo.environment)

And in a shell execute swiftc main.swift then ./main and you will see the use variables

But you can use the C function getenv

  • it take a UnsafePointer<Int8> which is the key you need (ie: "HOME") : a C char *
  • An return a UnsafeMutablePointer<Int8>! : The value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM