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;
}
精彩评论