Странная проблема вывода через NSPipe при выполнении команды оболочки с использованием NSTask

Вот мои коды. Когда я установил myCmd=@"cd /\nls -l\n" или же myCmd=@"ls -l\n", нет проблем. Тем не менее, когда я установил myCmd=@"cd /\n", программа не работает if ((output =[[outPipe fileHandleForReading] availableData]) && [output length]) и нет ничего отладочной информации.

Я не знаю, если "cd /" cmd отличается от другой команды оболочки. Не могли бы вы дать мне совет?

NSData *inputData = [myCmd dataUsingEncoding:NSUTF8StringEncoding];
NSPipe *inPipe = [NSPipe pipe];
NSFileHandle *fh = [inPipe fileHandleForWriting];
[fh writeData: inputData];
NSPipe *outPipe = [NSPipe pipe];
//NSPipe *errPipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
[task setStandardInput:inPipe];
[task setStandardOutput:outPipe];
[task setStandardError:outPipe];
[task setLaunchPath:@"/bin/sh"];
NSArray *args = [NSArray arrayWithObject:@"-s"];
[task setArguments:args];

[task launch];

NSData *output;
NSString *string;

if ((output =[[outPipe fileHandleForReading] availableData]) && [output length]) 
{
    string = [[NSString alloc] initWithFormat:@"%.s", [output bytes]];
}
NSLog(@"%@", string);

1 ответ

Решение

Я не знаю, если cd / cmd отличается от другой команды оболочки.

Это отличается от ls -l в том, что он не пишет никакого вывода. Ваша программа, вероятно, заблокирована при вызове -availableData,


К сожалению, у меня нет времени, чтобы попробовать какие-либо идеи, но вот некоторые вещи, которые вы могли бы попробовать.

  • Вы можете попробовать запустить задачу, затем отправить данные по входному каналу, а затем закрыть входной канал. Когда задача увидит конец ввода, она закроет канал вывода, что означает, что ваш вызов -availableData вернется с конца файла.

  • Вы можете читать вывод асинхронно, используя цикл выполнения. Это более гибко, так как вам не нужно отправлять все команды одновременно. Вам все еще нужно закрыть ввод, когда вы закончите.

  • Вы можете прочитать вывод в NSOperation, который фактически помещает его в другой поток. Опять же, вам все равно нужно закрыть входной канал, когда вы закончите.

Я должен отметить, кстати, что отправка cd для оболочки, как последнее, что вы делаете, это бессмысленная операция. Следующее, что происходит, это то, что оболочка выходит и cd результаты потеряны. Если вашей целью является изменение каталога в текущем процессе, посмотрите на [NSFilemanager changeCurrentDirectoryPath:]

Другие вопросы по тегам