Getting shell script output in Cocoa

Is there a way that allows me to run a shell script and display the output in the NSTextView? I don't want to enter the user into a shell script at all, as it is just called to compile the buch files. The shell script part is working so far, but I just can't figure out how to start it and show the output in the NSTextView. I know that a shell script can be run with system () and NSTask, but how can I get its output in NSTextView?

+2


a source to share


2 answers


If you want to unblock the extension, pass the 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;

}

      

+3


a source


NSTask

has a method setStandardOutput

that takes an object NSFileHandle

or NSPipe

. So if you instantiate an object NSPipe

and set it as NSTask

standardOutput

, you can use NSPipe

fileHandleForReading

to get NSFileHandle

from which in turn you can readDataToEndOfFile

or readDataOfLength:

you want. So something like this (code untested):



- (void)setupTask {
  // assume it 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;
}

      

+1


a source







All Articles