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

时间:2016-04-24 13:27:08

标签: swift macos nstask

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

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它运行完美没有任何问题,现在你如何让它工作?感谢。

2 个答案:

答案 0 :(得分:6)

bash有三种主要的操作模式:

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

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

  3. 如果您没有传递任何参数,它将从标准输入读取并执行命令。

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

    • 如果你正在尝试执行二进制文件(例如/ bin / echo),只需直接执行它而不使用bash:

      task.launchPath = "/bin/echo"
      task.arguments = ["1234"]
      
    • 如果你需要执行一个命令字符串(即如果你需要shell在执行它之前解析它,所以例如通配符扩展,或者有多个命令,或者......),请使用{{ 1}}:

      bash -c
    • 如果您需要执行实际脚本,即包含shell命令的文件,请单独留下task.launchPath = "/bin/bash" task.arguments = ["-c", "/bin/echo 1234; ls *"] ,但将其传递给实际脚本:

      runTask

答案 1 :(得分:1)

您正在执行不在Terminal.app中工作的/bin/bash /bin/echo

删除/bin/bash

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