我正在尝试让NSTask运行这样的命令:
ps -clx | grep'Finder'| awk'{print $ 2}'
这是我的方法
- (void) processByName:(NSString*)name {
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 waitUntilExit];
[task1 setLaunchPath: @"/bin/ps"];
[task1 setArguments: [NSArray arrayWithObjects: @"-clx", nil]];
[task1 setStandardOutput: pipe1];
NSTask *task2 = [[NSTask alloc] init];
NSPipe *pipe2 = [NSPipe pipe];
[task2 setLaunchPath: @"/usr/bin/grep"];
[task2 setArguments: [NSArray arrayWithObjects: @"'Finder'", nil]];
[task2 setStandardInput:pipe1];
[task2 setStandardOutput: pipe2];
NSTask *task3 = [[NSTask alloc] init];
NSPipe *pipe3 = [NSPipe pipe];
[task3 setLaunchPath: @"/usr/bin/grep"];
[task3 setArguments: [NSArray arrayWithObjects: @"'{print $2}'", nil]];
[task3 setStandardInput:pipe2];
[task3 setStandardOutput: pipe3];
NSFileHandle *file = [pipe3 fileHandleForReading];
[task1 launch];
[task2 launch];
[task3 launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);
}
但结果只是
结果:
我做错了什么?
修改
- (void) processByName:(NSString*)name {
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 waitUntilExit];
[task1 setLaunchPath: @"/bin/ps"];
[task1 setArguments: [NSArray arrayWithObjects: @"-clx", nil]];
[task1 setStandardOutput: pipe1];
NSTask *task2 = [[NSTask alloc] init];
NSPipe *pipe2 = [NSPipe pipe];
[task2 setLaunchPath: @"/usr/bin/grep"];
[task2 setArguments: [NSArray arrayWithObjects: @"'Finder'", nil]];
[task2 setStandardInput:pipe1];
[task2 setStandardOutput: pipe2];
NSTask *task3 = [[NSTask alloc] init];
NSPipe *pipe3 = [NSPipe pipe];
[task3 setLaunchPath: @"/usr/bin/grep"];
[task3 setArguments: [NSArray arrayWithObjects: @"'{print $2}'", nil]];
[task3 setStandardInput:pipe2];
[task3 setStandardOutput: pipe3];
NSFileHandle *file = [pipe3 fileHandleForReading];
[task1 launch];
[task2 launch];
[task3 launch];
[[NSNotificationCenter defaultCenter] addObserverForName:NSTaskDidTerminateNotification
object:task3
queue:nil
usingBlock:^(NSNotification* notification){
NSData * data = [file readDataToEndOfFile];
NSString * string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);
}];
}
答案 0 :(得分:5)
任务在与代码分开的进程中运行,即异步运行。当你稍后到达readDataToEndOfFile
两行时,它们可能还没有完成(它们可能还没有发射!)。
如果你已经在这里的后台线程,你可以轮询他们的状态:while( ![task isRunning]){
,或者如果你在主线程上,我建议使用GCD将其放入队列并进行那里的民意调查。
实际上,使用通知会更好:
[task3 launch];
[[NSNotificationCenter defaultCenter] addObserverForName:NSTaskDidTerminateNotification
object:task3
queue:nil
usingBlock:^{
NSData * data = [file readDataToEndOfFile];
NSString * string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);
}];
见TN2050: Observing Process Lifetime Without Polling。每个NSTask
在终止时都会发送NSTaskDidTerminateNotification
(理想情况下,您应该检查其返回代码,而不是假设它成功运行)。您可以创建一个在task3
发送该通知时运行的块。
答案 1 :(得分:2)
以下代码适用于我。
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 waitUntilExit];
[task1 setLaunchPath: @"/bin/sh"];
[task1 setArguments: [NSArray arrayWithObjects: @"-c",@"ps -A |grep -m1 Finder | awk '{print $1}'", nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];
NSString * string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);
答案 2 :(得分:0)
将近8年后,我认为grep二进制文件不在/ usr / bin中,对我而言,它在/ bin中。另外,对于awk命令,将启动路径设置为grep。