保持NSTask会话运行 - Cocoa

3

我在我的Cocoa应用程序中运行一个简单的grep命令,如下所示:

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/grep"];

NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"foo", @"bar.txt", nil];
[task setArguments: arguments];

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"grep returned:\n%@", string);

[string release];
[task release];

然而,我很好奇通过终端输入的不输出并且除非使用 Control + C 这样的退出方式,否则不能立即执行的命令是否可以使用此技术运行。例如运行 java -jar server.jar 使其一直运行直到退出会话。我该怎么做才能让会话在命令启动后不会自动结束呢?
我只需要注释掉释放 NSTask 的部分吗?任何建议都将是有益的!
1个回答

6
当使用带有不立即退出的基础程序的NSTask时:
  1. 不应该使用-[NSFileHandle readDataToEndOfFile],因为没有文件结束。相反,应该使用-[NSFileHandle readInBackgroundAndNotify]在后台读取该任务的标准输出管道,并在数据可用时得到通知;

  2. 只有在确定任务不再运行时才应该使用-[NSTask release]。在释放任务之前,应向其标准输入发送使底层程序退出的命令(例如等效于control-d的字符),或发送-terminate-interrupt

  3. 除非已经生成了一个次要线程来处理该任务,否则不应使用-waitUntilExit


1
实际上,你根本不应该使用 NSTask 来完成这个任务。相反,应该使用 Launchd,因为它允许服务器任务在应用程序外部进行维护,并且通常是专门设计来满足所描述的需求的。但如果你确实想使用 NSTask,那么 Bavarious 的答案完全正确。 - bbum
啊。那时我脑海中唯一的例子了。实际上我并没有将其用于服务器类型的情况。 - lab12
1
没有一个答案是完整的...你应该如何发送标准输入命令,以导致底层程序退出(例如等效于control-d的字符)?你应该如何使用Launchd代替?据我所知...launchd没有机制来监视父进程的生命周期,你很容易遇到僵尸子进程。这不好看。 - Alex Gray

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