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

5
我正在开发一个需要运行shell脚本的OS X应用程序。以下是我的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,它完美运行没有任何问题,那么如何让它工作呢?谢谢。

2个回答

14

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

  1. 如果你传递给它 -c "某个命令字符串" ,它将执行该命令字符串。

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

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

由于你传递给它的参数是 "/bin/echo" 和 "1234",它假定你想要第二种模式,因此尝试从 /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"])
    

1
你正在执行的是/bin/bash /bin/echo,在Terminal.app中也无法正常工作。
删除/bin/bash
task.launchPath = "/bin/echo"
...
runTask(["1234"])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接