我正在尝试使用基于 Swift 的 Mac 应用程序的命令行运行 Swift 脚本。
我有以下类方法,它接收参数并运行命令:
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
我能够成功执行如下命令:
shell("pwd")
shell("ls")
shell("swift")
pwd
按预期返回我的应用构建目录中的所有文件。这包括我手动添加的 hello.swift
文件,它只打印“Hello, world!”。此外,运行 swift
会授予对 Swift 环境的访问权限。
我不走运的是运行如下命令:
shell("swiftc hello.swift")
相反,我收到以下错误:
env: swiftc hello.swift: 没有那个文件或目录
看起来我正面临与这些帖子类似的情况:
Swift Process - execute command error
Running shell commands in Swift
但是,我不确定我是否完全理解其中对我的具体情况的所有影响。
最佳答案
澄清一下,在我们开始之前,swiftc
用于将 swift 脚本编译成二进制文件。相反,调用 swift
使用 swift 脚本文件,将解释给定的文件。
env: swiftc hello.swift: No such file or directory
本质上,这是在说明 env
正在向二进制文件传递两个参数:swiftc 和 hello.swift 并且不知道如何处理它。
task.launchPath = "/usr/bin/env"
我不确定你为什么调用 env
在这里,但假设我正确理解你的目标,我们可以使用 bash
以获得预期的结果。
假设我们有以下 script.swift 文件
#!/usr/bin/swift
import Foundation
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c"]
task.arguments = task.arguments! + args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
_ = shell("pwd")
_ = shell( "swift cmds.swift")
而不是调用 env
, 它正在使用 bash
.为了将字符串传递给 bash
它需要 -c
参数,我们在前面加上
task.arguments = ["-c"]
task.arguments = task.arguments! + args
可以看到脚本的末尾调用了文件 cmds.swift。如果我们通过解释器执行 script.swift,它将无法调用 cmds.swift - 本质上是从其内部调用解释器!
因此,我们将script.swift 编译为二进制文件:
swiftc script.swift
这会输出一个名为 script 的二进制文件。
正如我们所见,二进制调用 cmds.swift,所以让我们使用以下脚本代码创建它...
#!/usr/bin/swift
import Foundation
print("Hello World\n")
现在,如果我们执行我们编译的二进制文件,我们将看到它成功调用解释脚本并输出路径(来自 pwd)和来自调用 cmds.swift的“Hello World” em>.
关于swift - 从 Mac 应用程序运行 Swift 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48266983/