qed
qed

Reputation: 23134

How do you set environment vars for a process?

Copied from How do I run an terminal command in a swift script? (e.g. xcodebuild) :

import Foundation

@discardableResult
func shell(_ args: String...) -> Int32 {
    let task = Process()
    task.launchPath = "/usr/bin/env"
    task.arguments = args
    task.launch()
    task.waitUntilExit()
    return task.terminationStatus
}

shell("ls")
shell("xcodebuild", "-workspace", "myApp.xcworkspace")

This looks neat. I am just wondering how environment variables like $PWD can be set for the process (named task here...).


I tried the following:

import Foundation

@discardableResult
func execCommand(_ args: String...) -> Int32 {
    let process = Process()
    process.launchPath = "/usr/bin/env"
    process.environment = ["PWD": "/Users"]
    if let env = process.environment {
        print(env["PWD"] ?? "Unknown")
    } else {
        print("Environment not available!")
    }
    process.arguments = args
    process.launch()
    process.waitUntilExit()
    return process.terminationStatus
}


execCommand("pwd")

And got these lines printed:

/Users
/private/tmp/AppIcon.appiconset

Apparently the environment variable has been set, but has no effect on the pwd command at all.


Another approach:

import Foundation

@discardableResult
func execCommand(_ args: String...) -> Int32 {
    let process = Process()
    process.launchPath = "/usr/bin/env"
    var environment = ProcessInfo.processInfo.environment
    environment["PWD"] = "/Users" //optionally set new vars, or overwrite old ones
    process.environment = environment
    if let env = process.environment {
        print(env["PWD"] ?? "Unknown")
    } else {
        print("Environment not available!")
    }
    process.arguments = args
    process.launch()
    process.waitUntilExit()
    return process.terminationStatus
}


execCommand("pwd")

Unfortunately same results as before.

Upvotes: 4

Views: 4876

Answers (1)

Alexander
Alexander

Reputation: 63331

You just set the environment variable of the Process to a [String: String] containing the variable to value mappings.

let process = Process()
// ...
process.environment = ["home": "/Users/foo"]

If you want to pass on the current environment, you can do it like so:

let process = Process()
// ...
let environment = ProcessInfo.processInfo.environment
environment["home"] = "/Users/foo" //optionally set new vars, or overwrite old ones
process.environment = environment

If you want to set the working directory, that's not dictated by a environment variable, but rather, via the currentDirectoryPath property.

let process = Process()
// ...
process.currentDirectoryPath = "/Users"

Upvotes: 9

Related Questions