2012-02-22 71 views
4

我试图做一个NSTask运行如下命令:如何使用多个命令运行NSTask

PS -clx | grep'Finder'| AWK '{打印$ 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

在附加观察者之后启动任务会更有意义吗?如果任务在观察者被连接之前完成,该怎么办? – eonist 2016-12-16 12:58:23

回答

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发送该通知时,您可以创建一个要运行的块。

+0

您能否给我提供一个小例子,说明如何使用GCD来做到这一点? – dhrm 2012-02-22 18:36:38

+0

你知道,我只是想过一个更好的方法来做到这一点。请参阅我的编辑。 – 2012-02-22 18:50:09

+0

请参阅我的编辑。我已经添加了代码,但是我仍然返回一个空字符串。 – dhrm 2012-02-22 19:05:23

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);