我正在尝试使用基于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: No such file or directory
看起来我正面临着与这些帖子类似的情况:
Swift Process - execute command error
Running shell commands in Swift
但是,我不确定我是否完全理解其中对我的具体情况的所有影响。
答案 0 :(得分:1)
为了澄清,在我们开始之前,swiftc
用于将swift脚本编译成二进制文件。相反,使用swift脚本文件调用swift
将解释给定文件。
env:swiftc hello.swift:没有这样的文件或目录
基本上,这表明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)和&#34; Hello World&#34;来自调用< EM> cmds.swift