swift - 在 Cocoa 中使用 Swift 运行 Shell 脚本

标签 swift shell cocoa

我正在开发 Mac 桌面应用程序并尝试运行 shell 脚本。我在为任务设置启动路径时挂断了电话。这是代码:

    let path = fileURL.deletingLastPathComponent().relativePath

    //set new filename
    let strNewFileName = fileURL.deletingPathExtension().lastPathComponent.appending(".html")

    let newPath = path + "/" + strNewFileName

    //create script
    var strScript = "pandoc -s -o "
    strScript.append(newPath)
    strScript.append(" ")
    strScript.append(fileURL.absoluteString)

    //set storage path
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    var documentPath:URL = URL(string: documentsPath)!
    documentPath.appendPathComponent("pandoc.sh")

    var myURLComponents = URLComponents()
    myURLComponents.scheme = "file"
    myURLComponents.path = documentPath.absoluteString


    do {
        //write file
        try strScript.write(to: myURLComponents.url!, atomically: true, encoding: String.Encoding.utf8)

        //run script
        let myTask = Process()

        myTask.launchPath = "/usr/bin/env"
        myTask.arguments = [strScript]

        let myPipe = Pipe()
        myTask.standardOutput = myPipe

        myTask.launch()

        let data = myPipe.fileHandleForReading.readDataToEndOfFile()
        let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

        print(output!)



    } catch {
        print(error.localizedDescription)
    }

这会抛出一个没有这样的文件的错误:

env: pandoc -s -o /Users/stevensuranie/Desktop/MarkdownFiles/targeting-params-ios.html file:///Users/stevensuranie/Desktop/MarkdownFiles/targeting-params-ios.md: No such file or directory

如有任何帮助,我们将不胜感激。

最佳答案

这条线不行

var documentPath:URL = URL(string: documentsPath)!

URL(string适用于包含方案( file://https:// )的 URL 字符串,对于文件系统路径,您必须使用 URL(fileURLWithPath .

但是如果你使用FileManager的URL相关API你可以避免 init完全没有方法。
类似的问题是 absoluteString , 永远不要在文件系统 URL 上调用它,总是使用 path .

第二个致命问题是每个 shell 参数必须是 arguments 中的一个项目。数组和可执行文件必须指定完整路径

//create script
let scriptArguments = ["/path/to/pandoc", "-s", "-o", newPath, fileURL.path]

//set storage path
let documentsURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let scriptURL = documentsURL.appendingPathComponent("pandoc.sh")

以下几行是多余的 <罢工>

<罢工>
var myURLComponents = URLComponents()
myURLComponents.scheme = "file"
myURLComponents.path = documentPath.absoluteString

<罢工>

将字符串写入scriptURL

do {
    //write file
    try strScript.write(to: scriptURL, atomically: true, encoding: .utf8)
...

    myTask.arguments = scriptArguments

最后不要使用 NS... Swift 中的类

<罢工>

<罢工>
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

<罢工>

使用 native等效

let output = String(data: data, encoding: .utf8)

关于swift - 在 Cocoa 中使用 Swift 运行 Shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55423147/

相关文章:

unix - 从文件/grep 中删除重复的行

iphone - 是否可以在 iPhone 上录制 AAC/MP4 格式的音频?

swift - 如何在 Swift 中以编程方式旋转 USDZ 文件中的 3D 模型?

swift - 为什么消息不显示?

Linux Shell 脚本,$@ 不适用于别名

objective-c - 保留 NSLayoutConstraints 的常量

objective-c - 对于 10.7 中构建的应用程序,10.5 中未显示上下文菜单

ios - UIAlertController - 更改文本字段的大小并在它们之间添加空格

Swift:在所有屏幕上具有共享标题的 UITabBar

bash - 无法拆分存储在包含 $ 作为分隔符的变量中的字符串