【问题标题】:Getting output of a shell script in Cocoa在 Cocoa 中获取 shell 脚本的输出
【发布时间】:2010-05-16 05:32:31
【问题描述】:

有没有办法让我运行一个 shell 脚本,并在 NSTextView 中显示输出?我根本不希望用户向 shell 脚本输入任何内容,因为它只是被调用来编译大量文件。到目前为止,shell 脚本部分工作正常,但我只是不知道如何运行它并在 NSTextView 中显示输出。我知道可以使用 system() 和 NSTask 运行 shell 脚本,但是如何将其输出到 NSTextView 中?

【问题讨论】:

    标签: cocoa nstextview shell


    【解决方案1】:

    如果您想要通配符扩展,请将您的 unix 命令传递给 /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;
    
    }
    

    【讨论】:

      【解决方案2】:

      NSTask 具有setStandardOutput 方法,该方法接受NSFileHandleNSPipe 对象。因此,如果您创建NSPipe 对象并将其设置为NSTaskstandardOutput,那么您可以使用NSPipefileHandleForReading 来获取NSFileHandle,反过来,您将能够@ 987654331@ 或 readDataOfLength: 你想要的。所以这样的事情会做(代码未经测试):

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

      【讨论】:

      • 根据任务运行的时间长短,使用 NSFileHandle 的一种方法在后台读取数据可能会更好。
      • 我基本上是按照你上面说的做,并使用线程在后台运行更新输出字段,任务运行,但我在文本视图中从未看到任何东西。它接线正确。这是在后台运行的代码:'[N​​SThread detachNewThreadSelector: @selector(updateOutputField:) toTarget:self withObject: nil];'它在调试器中显示输出,但在文本字段中显示。启动它是这样的: [myTask setLaunchPath:@"/bin/sh"]; [myTask setArguments:[NSArray arrayWithObjects:scr], nil]]; [myTask setStandardOutput:standardOutputPipe]; [myTask 启动];
      猜你喜欢
      • 2022-11-24
      • 2018-09-06
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      • 2014-02-01
      • 1970-01-01
      相关资源
      最近更新 更多