【问题标题】:Execute a Swift script in terminal在终端中执行 Swift 脚本
【发布时间】:2017-09-13 16:31:57
【问题描述】:

我已经构建了一个命令行工具,在某些时候,我需要执行curl 命令。我正在创建应该执行的脚本,但我不知道如何。

我能够创建脚本并将其打印出来,但我无法执行它。
它看起来像:curl https://api.github.com/zen

如果不清楚,请随时问我。感谢您的帮助。

【问题讨论】:

  • 是否必须“发布”任何数据?
  • 不,所有数据都作为原始内容请求,并将显示在 CLI @mat 中
  • 我在这里质疑curl 的使用。 NSURLRequest 您可能会更轻松
  • 如果我在终端运行curl https://api.github.com/zen 命令,它将被执行。要执行相同的命令,我应该使用NSURLRequest 吗? @亚历山大

标签: swift bash shell command-line terminal


【解决方案1】:

您可以使用NSTask(现在在 Swift 3 中称为 Process)从 Swift 运行终端命令:如果您需要输出,请在末尾添加 let output = handle.readDataToEndOfFile()。这是封装在一个函数中的全部内容(launchPath 将是/usr/bin/curl):

func runTask(launchPath: String, flags: [String]) -> String {
    let task = Process()
    let pipe = Pipe()
    task.launchPath = launchPath
    task.arguments = flags
    task.standardOutput = pipe
    let handle = pipe.fileHandleForReading
    task.launch()
    return String(data: handle.readDataToEndOfFile(), encoding: .utf8) ?? ""
}

不过,在您的情况下,您可能想看看URLSessionURLRequest(取代NSURLRequest)。要创建对您的 URL 和凭据的请求,您只需执行以下操作:

    var request = URLRequest(url:URL(string: "https://api.github.com/zen")!)
    request.setValue("application/vnd.github.v3.raw", forHTTPHeaderField: "Accept")
    request.setValue("token USERTOKEN", forHTTPHeaderField: "Authorization")
    let session = URLSession(configuration: .default)
    session.dataTask(with: request, completionHandler: {(data, response, error) in
        guard let data = data, error == nil else {
            print("Error: \(error.debugDescription)")
            return
        }
        guard let output = String(data: data, encoding: .utf8) as String? else {
            print("Unable to format output data")
            return
        }
        print(output)
    }).resume()

【讨论】:

  • 感谢奥斯卡的帮助。在 runTask 函数中,我应该将什么传递给 launchPath?关于 URLSession,如果我有一个带有许多标志的命令,我应该怎么做?示例:curl -H 'Authorization: token USERTOKEN’ -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/USERNAME/REPO/contents/PATH@Oskar
  • 其实我不太确定要传递给var request = MutableURLRequest(URL:url) 中的url,这里是我在main.swift 中所做的:gist.github.com/MEnnabah/18ecf3fbd95ecee1466d08dab896fcc4 但它不起作用。
  • 第一种方法中的URL在哪里传递? @奥斯卡
  • 我已更新我的答案以使用带有标头的自定义请求。它应该可以使用,除非您需要提供有效的 USERTOKEN。
  • 非常抱歉,我在运行的应用程序中运行了该应用程序,我不确定为什么它没有在主文件中运行。非常感谢!
【解决方案2】:
#!/usr/bin/env swift

import Foundation

func run(_ args: String...) -> Int32 {
    let task = Process()
    task.launchPath = "/usr/bin/env"
    task.arguments = args
    task.launch()
    task.waitUntilExit()
    return task.terminationStatus
}

run("curl", "https://api.github.com/zen")

【讨论】:

  • 嗨,亚当,感谢您的回复,这对 curl https://api.github.com/zen 的示例很有帮助。但是,我试图通过在每个标志之间插入双引号和逗号来运行另一个命令,例如:curl -H 'Authorization: token USERTOKEN’ -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/USERNAME/REPO/contents/PATH,但我没有这样做。请帮帮我。如果您能详细解释上面的 func 是如何工作的,我也将不胜感激。谢谢
  • 该方法接受与您传递的参数一样多的参数。 run("curl", "param1", "param2", "paramn")。见[variadic parameters](swift variadic parameters)。
  • 该函数创建一个Process 来运行您传递给它的命令。
  • 是的,但我的问题是如何传递标头参数?
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 2011-01-11
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
相关资源
最近更新 更多