【问题标题】:How to get "continous" terminal execution output in a Cocoa app?如何在 Cocoa 应用程序中获得“连续”终端执行输出?
【发布时间】:2013-06-18 14:58:37
【问题描述】:

问别的方法:

例如,当我克隆一个 git repo 时,终端输出如下:

Cloning into '/users/whatever'...
remote: Counting objects: 1764, done.
remote: Compressing objects: 100% (909/909), done.
remote: Total 1764 (delta 944), reused 1622 (delta 820)
Receiving objects: 100% (1764/1764), 395.83 KiB | 139 KiB/s, done.
Resolving deltas: 100% (944/944), done.

但是当我从我的 Cocoa 应用程序中执行完全相同的命令时,它只输出:

Cloning into '/users/whatever'...

两个任务都只是执行,完成它们的工作。我唯一的问题是我无法使用前者向用户显示任何进展。


我原来的问题:

我可以在 Cocoa 中使用 NSTask 和 NSPipe 愉快地运行同步“终端命令”,如下所示。

-(NSString*)execute:(NSString*) command
{
    NSTask *task = [NSTask new];
    [task setLaunchPath:@"/bin/sh"];
    [task setArguments:[NSArray arrayWithObjects:@"-c", command, nil]];

    NSPipe *pipe = [NSPipe pipe];

        [task setStandardOutput:pipe];
        [task setStandardError:pipe];
        [task launch];

    NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
    [task waitUntilExit];

    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

但是当我启动一个具有“持续更新”输出的任务(想想“git clone”或类似的)时,我无法获得完整的输出流程

如何克服这个问题? NSPipe 有一些异步委托方法吗?还是我应该设置一个计时器并继续询问 NSPipe 实例的当前状态?还是NSTask?有我可以实现的处理程序块吗?

我对 Cocoa 非常陌生(我主要是 iOS),所以我不知道如何解决这个问题。

【问题讨论】:

  • 我试过用 setReadabilityHandler: 观察输出文件处理程序,但输出是一样的,只有一行。 :(
  • 更重要的是,我尝试在一段时间{}块内继续轮询文件处理程序,但结果也是一样的。
  • 甚至没有 NSFileHandleDataAvailableNotification。
  • 是带有“git clone”输出的东西吗?我应该尝试另一个命令吗?
  • 尝试将 'waitUntilExit' 行移到 readDataToEndOfFile 行之前。如果这不起作用,请尝试注释掉setStandardOutput: 行一次,下一次注释掉setStandardError: 行。在我的脑海中,我不确定您是否可以为两者使用相同的管道。

标签: macos cocoa terminal nstask


【解决方案1】:

您正在阻止“readDataToEndOfFile” - 相反,您需要使用“readInBackgroundAndNotify”。

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 2013-03-22
    • 2019-04-10
    • 2015-01-01
    • 1970-01-01
    • 2015-11-07
    • 2020-08-23
    • 2012-01-25
    • 2018-10-26
    相关资源
    最近更新 更多