swift - 从 Mac 应用程序运行 Swift 命令

标签 swift xcode bash macos shell

我正在尝试使用基于 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正在向二进制文件传递两个参数:swiftchello.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.

关于swift - 从 Mac 应用程序运行 Swift 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48266983/

相关文章:

bash - 在 cut 的输出中保留分隔符

Bash [[ 测试,引用变量

ios - CloudKit 记录的本地缓存

swift - 在 Swift 中将日期转换为整数

swift - 连接 IBOutlet 时 IBAction 停止工作

ios - 导入音频播放器包后无法运行 flutter

ios - 向NotificationCenter观察者添加参数UIbutton

ios - 返回 POST 请求的 Alamofire 路由器

ios - 如何在 NSMutableAttributedString 中传递两个字符串

linux - Bash 脚本如果已经运行则等待,然后继续