【问题标题】:How to run a Process in Swift 3.0 with standard input如何使用标准输入在 Swift 3.0 中运行进程
【发布时间】:2017-11-22 01:57:16
【问题描述】:

使用 Swift Process 运行 MySQL 还原转储文件时遇到问题。

let command = "/usr/local/bin/mysql -h theHost -P 3306 -u root -pTheInlinePassword example_database < dumpFile.sql"
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = command.components(separatedBy: " ")
task.launch()

问题是进程不理解标准输入&lt;。我怎样才能像这样使用标准输入运行命令?谢谢。

更新:

let task = Process()
task.launchPath = "/usr/local/bin/mysql"
task.arguments =  ["-h", "theHost", "-P", "3306", "-u", "root", "-pTheInLinePassword", "example_data"]
task.standardInput = try! FileHandle(forReadingFrom: filePath!)
task.launch()

我尝试了下面的代码。这对我有用

【问题讨论】:

    标签: mysql swift macos shell


    【解决方案1】:

    &lt; filename 语法是 shell 提供的一项功能,而不是程序本身处理的东西。

    处理此问题的正确方法是构造一个FileHandle 用于从dumpFile.sql 读取,然后将FileHandle 设置为standardInputstandardInput 属性Process

    附带说明一下,我不知道您为什么使用 /usr/bin/env 作为启动路径,因为您不依赖 PATH 查找或设置任何环境变量。

    let input = try FileHandle(forReadingFrom: URL(fileURLWithPath: "dumpFile.sql"))
    let task = Process()
    task.launchPath = "/usr/bin/mysql"
    task.arguments = ["-h", "theHost", "-P", "3306", "-u", "root", "-pTheInlinePassword", "example_database"]
    task.standardInput = input
    task.launch()
    

    【讨论】:

    • FileHandle(forReadingAtPath: "dumpFile.sql")
    • 您也可以使用它,但如果文件不存在而 URL 版本会引发错误,则会返回 nil。因此,如果您使用字符串版本,请确保处理 nil 值。
    • 谢谢凯文和马丁,我现在就试试
    • @Max:如果有帮助,您可以通过单击复选标记接受答案。见meta.stackexchange.com/a/5235/196432
    【解决方案2】:

    我一直在尝试使用 Process 让它工作一段时间,但没有成功。然而,真正起作用的是深入研究了一些达尔文框架并使用了 posix_spawn。

    此脚本将生成一个子进程并将控制权交给它,直到进程终止(很像 Python 中的 os.system 调用)。

    import Darwin
    
    func run(_ cmd: String) -> Int32 {
        var pid: Int32 = 0
        let args = ["/bin/sh", "-c", cmd]
        let argv: [UnsafeMutablePointer<CChar>?] = args.map{ $0.withCString(strdup) }
        defer { for case let arg? in argv { free(arg) } }
        if posix_spawn(&pid, argv[0], nil, nil, argv + [nil], environ) < 0 {
            print("ERROR: Unable to spawn")
            return 1
        }
        var status: Int32 = 0
        _ = waitpid(pid, &status, 0)
        return status
    }
    

    我相信这个脚本可以改进,但可能会让你更接近你想去的地方。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2011-12-31
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      • 2012-09-18
      相关资源
      最近更新 更多