我想在cocoa应用程序中调用unix命令,但它不起作用,

我想在cocoa应用程序中调用unix命令,但它不起作用,,cocoa,unix,command,Cocoa,Unix,Command,我想在cocoa应用程序中调用unix命令,但它不起作用 命令:lua-v 可可代码: NSArray *cmdArray = [cmd componentsSeparatedByString:@" "]; NSPipe *pipe = [NSPipe pipe]; NSFileHandle *file = pipe.fileHandleForReading; NSTask *task = [[NSTask alloc] init]; [task setStandardOutput:pipe]

我想在cocoa应用程序中调用unix命令,但它不起作用

命令:lua-v

可可代码:

NSArray *cmdArray = [cmd componentsSeparatedByString:@" "];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

NSTask *task = [[NSTask alloc] init];
[task setStandardOutput:pipe];
task.launchPath = cmdArray[0];
if(cmdArray.count > 1)
{
    task.arguments = [cmdArray subarrayWithRange:NSMakeRange(1, cmdArray.count - 1)];
}
[task launch] ;
NSData *data = [file readDataToEndOfFile];
[file closeFile] ;

NSString *grepOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return grepOutput;
数据始终为0字节

NSTask不运行Unix命令,而是运行Unix进程,两者之间的差异至关重要

当您的代码在Xcode中运行时,您应该会在控制台窗口中看到无法访问的启动路径,这是您关于问题的线索。启动文档告诉您,如果启动路径无效,将引发异常

例如,在Unix命令提示符下键入echo Hello时,您正在将数据输入命令解释器shell。shell必须找到应用程序echo才能启动运行它的进程。shell通过搜索PATH环境变量指定的一组目录来实现这一点,对于echo,它找到/bin/echo。必须将launchPath属性设置为该路径

如果您希望为此目的使用NSTask,您有两个基本选择a让您的代码定位lua二进制文件本身,或b使用NSTask运行shell并让该shell为您执行其正常处理

标准的sh shell位于/bin/sh。如果您阅读它的手册页面,您将看到它使用了一个选项-c string,该选项指示它将string作为命令输入。请考虑以下的终端记录:

crd$ echo Hello
Hello
crd$ sh -c "echo Hello"
Hello
crd$
在第一种情况下,shell找到echo的二进制文件,并将其传递给Hello执行。在第二个过程中,它找到了sh的二进制文件,并执行了传递-c和echo Hello的过程,该过程又找到了echo的二进制文件

因此,使用NSTask,您可以调用/bin/sh并将其作为参数-c和您的命令行传递,然后shell将像在终端中一样解析您的命令行并调用您的命令,如下所示:

NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

NSTask *task = [[NSTask alloc] init];
task.standardOutput = pipe;
task.standardError =pipe;  // capture any error messages the sh writes, could send to another pipe
task.launchPath = @"/bin/sh";
task.arguments = @[@"-c", cmd];

[task launch];
NSData *data = [file readDataToEndOfFile];
[file closeFile];