How to start NSTask with several commands

I am trying to make NSTask by running the command as follows:

ps -clx | grep 'Finder' | awk '{print $ 2}'

Here is my method

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

But the result is simply

Result:

What am I doing wrong?

EDIT

 - (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); }]; } 
+4
objective-c nstask
source share
2 answers

Tasks are launched in a separate process from your code, i.e. asynchronously. They probably haven’t finished yet (maybe they haven’t even started!) By the time of transition to readDataToEndOfFile two lines later.

If you are already in the background thread, you can poll their status: while( ![task isRunning]){ , or if you are in the main thread, I would suggest using GCD to put this in the queue and there is a poll.

Actually, it is better to use notifications:

 [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); }]; 

See TN2050: adherence to process time without polling Each NSTask sends an NSTaskDidTerminateNotification when it completes (you should ideally check its return code, and not consider it successful). You can create a block that will run when task3 sends this notification.

+5
source share

The following code works for me.

 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
source share

All Articles