Странная проблема вывода через 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:]