Note that there are some explanatory texts on larger screens.

plurals
  1. PONSTask/NSPipe read from Unix command
    primarykey
    data
    text
    <p>I am writing a Cocoa application which needs to execute a UNIX program and read its output, line by line, as they are produced. I set up a NSTask and NSPipe as such:</p> <pre><code>task = [[NSTask alloc] init]; pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; //... later ... [task setArguments:...]; [task setLaunchPath:@"..."]; [task launch]; handle = [[task fileHandleForReading] retain]; </code></pre> <p>The command does not terminate until the program tells it to do so with <code>[task terminate]</code>. I have tried several methods of reading from the handle, such as <code>-readInBackgroundAndNotify</code>, <code>while([(data = [handle availableData]) length] &gt; 0)</code>, and <code>-waitForDataInBackgroundAndNotify</code>, but the pipe never seems to yield any data. Is there some way I can "poke" the <code>NSTask</code> or <code>NSPipe</code> to flush the data through?</p> <p><strong>EDIT</strong>: with <code>-readInBackgroundAndNotify</code>:</p> <pre><code>[handle readInBackgroundAndNotify]; notification_block_t handlerBlock = ^(NSNotification *notification) { NSData *data = [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem]; /*... do stuff ...*/ [self addNotification: handle block: handlerBlock]; }; [self addNotification: handler block: handlerBlock]; //... - (void)addNotification:(id)handle block:(notification_block_t)block { [[NSNotificationCenter defaultCenter] addObserverForName: NSFileHandleReadCompletionNotification object: handle queue: [NSOperationQueue mainQueue] usingBlock: block]; } </code></pre> <p>with <code>-waitForDataInBackgroundAndNotify</code>:</p> <pre><code>[handle waitForDataInBackgroundAndNotify]; notification_block_t handlerBlock = ^(NSNotification *notification) { NSData *data = [handle availableData]; /*... do stuff ...*/ }; [self addNotification: handler block: handlerBlock]; </code></pre> <p>with <code>while</code> loop:</p> <pre><code>[self startProcessingThread: handle]; //... - (void)startProcessingThread:(NSFileHandle *)handle { [[NSOperationQueue mainQueue] addOperation: [[[NSInvocationOperation alloc] initWithTarget: self selector: @selector(dataLoop:) object: handle] autorelease]]; } - (void)dataLoop:(NSFileHandle *)handle { NSData *data; while([(data = [handle availableData]) length] &gt; 0) { /*... do stuff ...*/ } } </code></pre> <p><strong>EDIT 2</strong>: The arguments are set as follows (the command is <code>tshark</code>):</p> <pre><code>NSArray *cmd = [NSArray arrayWithObjects:@"-R", @"http.request", @"-Tfields", @"-Eseparator='|'", @"-ehttp.host", @"-ehttp.request.method", @"-ehttp.request.uri", nil]; cmd = [[cmd arrayByAddingObjectsFromArray:[self.ports map:^(id arg1, NSUInteger idx) { return [NSString stringWithFormat:@"-d tcp.port==%d,http", [arg1 intValue]]; }]] arrayByAddingObject:[@"dst " stringByAppendingString: [self.hosts componentsJoinedByString:@" or dst "]]]; [self.tsharktask setArguments:cmd]; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload