我正在寻找一种在 Swift 脚本中运行 shell 命令的解决方案。
这是我的代码:
func shellEnv(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/zsh"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
它适用于内置命令,但不能处理诸如“brew”、“node”和其他手动安装的命令之类的命令。
那我该如何解决呢?
答案 0 :(得分:2)
您需要为 PATH
设置 task
环境变量。这已在您的终端中设置,这就是为什么您可以直接执行 brew
和 node
以及其他很酷的事情,而无需指定它们的完整路径。
您可以通过执行以下操作来查看终端中的设置:
echo $PATH
它会打印出类似的东西(对我来说它还有很多东西。这只是摘录):
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
如果您复制并粘贴 echo $PATH
的整个输出,并将其放入 environment
的 task
属性中,那么您将能够在 swift 脚本中使用相同的命令就像在您的终端中一样。
task.environment = ["PATH": "<paste the output here>"]
正如 Alexander 在 comments 中所说,另一种方法是添加 l
选项。这是一个 MCVE:
#!/usr/bin/swift
// main.swift
import AppKit
func shellEnv(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-cl", command]
task.launchPath = "/bin/zsh"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
print(shellEnv("brew list")) // assuming you have brew
要运行,chmod +x main.swift
然后 ./main.swift
,您将看到列出的所有自制软件包。