У меня есть простой скрипт Python, который запрашивает ваше имя, а затем выдает его обратно:
def main():
print('Enter your name: ')
for line in sys.stdin:
print 'You entered: ' + line
Довольно простые вещи! При запуске этого в терминале OS X он отлично работает:
$ python nameTest.py
Enter your name:
Craig^D
You entered: Craig
Но при попытке запустить этот процесс через NSTask
стандартный вывод появляется только в том случае, если в сценарий Python добавлены дополнительные вызовы flush().
Вот как я настроил NSTask
и трубопровод:
NSTask *_currentTask = [[NSTask alloc] init];
_currentTask.launchPath = @"/usr/bin/python";
_currentTask.arguments = [NSArray arrayWithObject:@"nameTest.py"];
NSPipe *pipe = [[NSPipe alloc] init];
_currentTask.standardOutput = pipe;
_currentTask.standardError = pipe;
dispatch_queue_t stdout_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
__block dispatch_block_t checkBlock;
checkBlock = ^{
NSData *readData = [[pipe fileHandleForReading] availableData];
NSString *consoleOutput = [[NSString alloc] initWithData:readData encoding:NSUTF8StringEncoding];
dispatch_sync(dispatch_get_main_queue(), ^{
[self.consoleView appendString:consoleOutput];
});
if ([_currentTask isRunning]) {
[NSThread sleepForTimeInterval:0.1];
checkBlock();
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
NSData *readData = [[pipe fileHandleForReading] readDataToEndOfFile];
NSString *consoleOutput = [[NSString alloc] initWithData:readData encoding:NSUTF8StringEncoding];
[self.consoleView appendString:consoleOutput];
});
}
};
dispatch_async(stdout_queue, checkBlock);
[_currentTask launch];
Но при запуске NSTask
это выглядит так (сначала оно пустое, но после ввода моего имени и нажатия CTRL+D все сразу заканчивается):
Craig^DEnter your name:
You entered: Craig
Итак, мой вопрос: как я могу прочитать stdout
из моего NSTask
, не требуя дополнительных операторов flush() в моем скрипте Python? Почему приглашение Введите свое имя: не появляется сразу при запуске от имени NSTask
?