NSTask /bin/echo: /bin/echo: 无法执行二进制文件

NSTask /bin/echo: /bin/echo: cannot execute binary file

我正在制作一个 OS X 应用程序,它需要 运行 一个 shell 脚本。这是我的 swift 代码:

func runTask(arguments: [String]) {
    output.string = ""

    task = NSTask()
    task.launchPath = "/bin/bash"
    task.arguments = arguments;

    errorPipe = NSPipe()
    outputPipe = NSPipe()

    task.standardError = errorPipe
    task.standardOutput = outputPipe

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(didCompleteReadingFileHandle(_:)), name: NSFileHandleReadCompletionNotification, object: task.standardOutput!.fileHandleForReading)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(didCompleteReadingFileHandle(_:)), name: NSFileHandleReadCompletionNotification, object: task.standardError!.fileHandleForReading)

    errorPipe.fileHandleForReading.readInBackgroundAndNotify()
    outputPipe.fileHandleForReading.readInBackgroundAndNotify()

    task.launch()
}

func didCompleteReadingFileHandle(sender: NSNotification) {
    let data: NSData = sender.userInfo![NSFileHandleNotificationDataItem] as! NSData;
    let string = NSString(data: data, encoding: NSUTF8StringEncoding)!
    // The output property is a NSTextView object
    output.string?.appendContentsOf(String(string))
}

现在我尝试调用 runTask 方法:

runTask(["/bin/echo", "1234"])

提示以下错误:

/bin/echo: /bin/echo: cannot execute binary file

现在我回到终端并输入 echo 1234 它运行完美,没有任何问题,现在你如何让它工作?谢谢。

您正在执行 /bin/bash /bin/echo,这在 Terminal.app 中也不起作用。

删除/bin/bash

task.launchPath = "/bin/echo"
...
runTask(["1234"])

bash主要有三种操作模式:

  1. 如果你传递它-c "some command string",它会执行那个命令字符串。

  2. 如果您将文件路径作为参数传递给它,它将从该文件中读取命令并执行它们(即,将文件作为 shell 脚本执行)。

  3. 如果你不给它传递任何参数,它会从标准输入读取并执行命令。

由于您向它传递了参数“/bin/echo”和“1234”,它假定您需要模式 2,因此它会尝试从 /bin/echo 读取 shell 命令,但失败了.我不清楚你到底想达到什么目的,但我看到了几个可能相关的选项:

  • 如果你试图执行一个二进制文件(例如/bin/echo),直接执行它,根本不使用bash:

    task.launchPath = "/bin/echo"
    task.arguments = ["1234"]
    
  • 如果您需要执行一个命令字符串(即如果您需要 shell 在执行之前对其进行解析,例如通配符被扩展,或者有多个命令,或者...), 使用 bash -c:

    task.launchPath = "/bin/bash"
    task.arguments = ["-c", "/bin/echo 1234; ls *"]
    
  • 如果你需要执行一个实际的脚本,即一个包含 shell 命令的文件,那么不要管 runTask,而是将一个实际的脚本传递给它:

    runTask(["/path/to/script", "scriptarg", "another argument"])