开发者

Getting output of a shell script in Cocoa

Is there a way that lets me run a shell script, and display the output in an NSTextView? I do not want any input from the user to the shell script at all, since is is just called to compile a buch of files. The shell script part works fine so far, but I just can't figure out how to run it and show the output in an NSTextVie开发者_如何学Gow. I know a shell script can be run using system() and NSTask, but how do I get it's output into an NSTextView?


If you want wildcard expansion then pass your unix command to /bin/sh

- (NSString *)unixSinglePathCommandWithReturn:(NSString *) command {
    // performs a unix command by sending it to /bin/sh and returns stdout.
    // trims trailing carriage return
    // not as efficient as running command directly, but provides wildcard expansion

    NSPipe *newPipe = [NSPipe pipe];
    NSFileHandle *readHandle = [newPipe fileHandleForReading];
    NSData *inData = nil;
    NSString* returnValue = nil;

    NSTask * unixTask = [[NSTask alloc] init];
    [unixTask setStandardOutput:newPipe];
    [unixTask setLaunchPath:@"/bin/csh"];
    [unixTask setArguments:[NSArray arrayWithObjects:@"-c", command , nil]]; 
    [unixTask launch];
    [unixTask waitUntilExit];
    int status = [unixTask terminationStatus];

    while ((inData = [readHandle availableData]) && [inData length]) {

        returnValue= [[NSString alloc] 
                      initWithData:inData encoding:[NSString defaultCStringEncoding]];

        returnValue = [returnValue substringToIndex:[returnValue length]-1];

        NSLog(@"%@",returnValue);
    }

    return returnValue;

}


NSTask has setStandardOutput method that accepts either NSFileHandle or NSPipe object. So if you create NSPipe object and set it as NSTask's standardOutput then you could use NSPipe's fileHandleForReading to get NSFileHandle from which, in turn, you'll be able to readDataToEndOfFile or readDataOfLength: you want. So something like this would do (code untested):

- (void)setupTask {
  // assume it's an ivar
  standardOutputPipe = [[NSPipe alloc] init];
  [myTask setStandardOutput:standardOutputPipe];
  // other setup code goes below
}

// reading data to NSTextField
- (void)updateOutputField {
  NSFileHandle *readingFileHandle = [standardOutputPipe fileHandleForReading];
  NSData *newData;
  while ((newData = [readingFileHandle availableData])) {
    NSString *newString = [[[NSString alloc] initWithData:newData encoding: NSASCIIStringEncoding] autorelease];
    NSString *wholeString = [[myTextField stringValue] stringByAppendingString:newString];
    [myTextField setStringValue:wholeString];
  }
  [standardOutputPipe release];
  standardOutputPipe = nil;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜