【问题标题】:Objective-c: How to use NSPipe output the illegal command echo in a NSTask?Objective-c:如何使用 NSPipe 在 NSTask 中输出非法命令 echo?
【发布时间】:2012-05-16 15:04:58
【问题描述】:

我有如下代码,没关系,但我有两个问题。

1) 如果我为 sh 分配了一些非法参数,例如@"ls - l",那么 outString 为空。也就是无法捕捉到错误警告“ls: -: No such file or directory ls:l:No such file or directory”。如何处理?

2)如何实现这个功能:假设应用的当前目录是"/user/Doc",我执行sh = @"cd /",然后我执行 sh = @"ls -l" 来查看“/”下的内容 下一个循环的目录。但是当新循环开始时,当前目录恢复到“/user/Doc”。怎样才能保持上次循环的任务环境?

此外,我可以像直接在终端上工作一样,继续运行“/bin/sh”吗?

NSString *sh = @"ls -l";
while(sh != @"end"){
    NSTask *shData = [[NSTask alloc] init];
    [shData setLaunchPath: @"/bin/sh"];

    NSArray *args;
    args = [NSArray arrayWithObjects: @"-c", sh, nil];
    [shData setArguments: args];

    NSPipe *myPipe;
    myPipe = [NSPipe pipe];
    [shData setStandardOutput: myPipe];
    [shData setStandardInput:[NSPipe pipe]];

    NSFileHandle *file;
    file = [myPipe fileHandleForReading];

    [shData launch];

    NSData *data1;    
    data1 = [file readDataToEndOfFile];

    NSString *outString;
    outString = [[NSString alloc] initWithData: data1 encoding: NSUTF8StringEncoding];

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

【问题讨论】:

  • 对于工作目录,为什么不直接使用-[NSTask setCurrentDirectoryPath:]
  • 这不是我需要的。我的目的是使用不同的参数连续运行任务,但要求下一次运行的环境由最后一次运行输出决定。例如,我运行“cd /”任务后,我想运行“ls -l”来显示目录“/”下的所有内容,这是运行“cd /”的结果。
  • Apple 的文档说:“一个 NSTask 对象只能运行一次。”如果有其他方法可以让 shell 子进程在运行时保留并接收 args?
  • 如果您想要一个可以向其提供一系列命令的 shell,请不要传递“-c”和命令。而是在没有参数或使用“-s”的情况下启动它。然后将“ls -l\n”(注意换行符)之类的命令写入连接到标准输入的管道。
  • 你能给出一些示例代码吗?

标签: objective-c shell nstask nspipe


【解决方案1】:
  1. 该字符串是标准错误,而不是标准输出。由于你不检查错误流,所以你不会找到它。

  2. 子shell 不是这样工作的。谷歌“为什么 cd 是一个内置的 shell”以获得大量信息。

【讨论】:

  • 谢谢,卡尔。可以给我一些标准错误检查的示例代码吗?
  • @TomJacky 那是[shData setStandardError:myPipe];
  • 同时读取标准输出和标准错误时出现问题。如果您尝试将一个读取到 EOF 然后另一个,您可能会锁定。问题是子进程可能正在尝试写入您没有阅读的那个。如果它写入的内容足以填充管道的内核缓冲区,它将阻塞等待读取器(此代码)从中读取,但读取器会阻塞等待另一个管道关闭。您必须使用 -[NSFileHandle readToEndOfFileInBackgroundAndNotify] 之类的内容异步读取其中至少一个。
  • @CarlNorum 第一个问题已解决,但我仍然对第二个问题感到困惑。我的问题是因为 NSTask 功能“一个 NSTask 对象只能运行一次”吗?
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 2012-11-03
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
相关资源
最近更新 更多