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主要有三种操作模式:
如果你传递它-c "some command string"
,它会执行那个命令字符串。
如果您将文件路径作为参数传递给它,它将从该文件中读取命令并执行它们(即,将文件作为 shell 脚本执行)。
如果你不给它传递任何参数,它会从标准输入读取并执行命令。
由于您向它传递了参数“/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"])
我正在制作一个 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主要有三种操作模式:
如果你传递它
-c "some command string"
,它会执行那个命令字符串。如果您将文件路径作为参数传递给它,它将从该文件中读取命令并执行它们(即,将文件作为 shell 脚本执行)。
如果你不给它传递任何参数,它会从标准输入读取并执行命令。
由于您向它传递了参数“/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"])