如何在Swift脚本中通过Zsh设置环境变量

时间:2020-01-26 10:42:00

标签: swift shell zsh

考虑以下Swift脚本(Shell.swift):

#!/usr/bin/swift

import Foundation

func shell(_ command: String) {
    let task = Process()
    task.launchPath = "/bin/zsh"
    task.arguments = ["-c", command]

    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8) ?? ""
    print(output)
}

如果我在末尾添加此行:

shell("date")

...,然后像这样从我的终端调用它:

$ ./Shell.swift

输出为:

Sun Jan 26 11:35:52 CET 2020

如果我添加以下行:

shell("echo $LANG")

输出为:

en_US.UTF-8

它按预期工作。

现在,如果我添加这些行:

shell("export MY_VAR=123")
shell("echo $MY_VAR") ?? // Nothing is printed out

有没有办法做到这一点?

如何在Swift脚本中通过Zsh设置环境变量?

1 个答案:

答案 0 :(得分:1)

shell()函数的每次调用都会产生一个新的Z shell,并且在第一次调用中设置环境变量不会影响第二次调用的环境。

以下是一些选项:您可以在要执行的zsh脚本中设置环境。示例:

shell("date")
// Sun Jan 26 11:56:25 CET 2020

shell("export TZ=UTC ; date")
// Sun Jan 26 10:56:25 UTC 2020

或者您可以通过将指定的环境变量添加到默认环境中来设置task.environment

func shell(_ command: String, addEnvironment: [String: String]? = nil) {
    let task = Process()
    task.launchPath = "/bin/zsh"
    task.arguments = ["-c", command]
    if let addEnv = addEnvironment {
        var currentEnv = ProcessInfo.processInfo.environment
        for (key, value) in addEnv {
            currentEnv[key] = value
        }
        task.environment = currentEnv
    }

    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8) ?? ""
    print(output)
}

示例:

shell("date", addEnvironment: ["TZ": "UTC"])
// Sun Jan 26 10:56:25 UTC 2020