Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8829185
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T07:46:40+00:00 2026-06-14T07:46:40+00:00

I have a simple Python script that asks for your name, then spits it

  • 0

I have a simple Python script that asks for your name, then spits it back out:

def main():
    print('Enter your name: ')
    for line in sys.stdin:
        print 'You entered: ' + line

Pretty simple stuff! When running this in the OS X Terminal, it works great:

$ python nameTest.py 
Enter your name: 
Craig^D
You entered: Craig

But, when attempting to run this process via an NSTask, the stdout only appears if additional flush() calls are added to the Python script.

This is how I have my NSTask and piping configured:

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];

But when running the NSTask, this is how it appears (it is initially blank, but after entering my name and pressing CTRL+D, it finishes all at once):

Craig^DEnter your name: 
You entered: Craig

So, my question is: How can I read the stdout from my NSTask without requiring the additional flush() statements in my Python script? Why does the Enter your name: prompt not appear immediately when run as an NSTask?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T07:46:42+00:00Added an answer on June 14, 2026 at 7:46 am

    When Python sees that its standard output is a terminal, it arranges to automatically flush sys.stdout when the script reads from sys.stdin. When you run the script using NSTask, the script’s standard output is a pipe, not a terminal.

    UPDATE

    There is a Python-specific solution to this. You can pass the -u flag to the Python interpreter (e.g. _currentTask.arguments = @[ @"-u", @"nameTest.py"];), which tells Python not to buffer standard input, standard output, or standard error at all. You can also set PYTHONUNBUFFERED=1 in the process’s environment to achieve the same effect.

    ORIGINAL

    A more general solution that applies to any program uses what’s called a “pseudo-terminal” (or, historically, a “pseudo-teletype”), which we shorten to just “pty”. (In fact, this is what the Terminal app itself does. It is a rare Mac that has a physical terminal or teletype connected to a serial port!)

    Each pty is actually a pair of virtual devices: a slave device and a master device. The bytes you write to the master, you can read from the slave, and vice versa. So these devices are more like sockets (which are bidirectional) than like pipes (which are one-directional). In addition, a pty also let you set terminal I/O flags (or “termios”) that control whether the slave echoes its input, whether it passes on its input a line at a time or a character at a time, and more.

    Anyway, you can open a master/slave pair easily with the openpty function. Here’s a little category that you can use to make an NSTask object use the slave side for the task’s standard input and output.

    NSTask+PTY.h

    @interface NSTask (PTY)
    
    - (NSFileHandle *)masterSideOfPTYOrError:(NSError **)error;
    
    @end
    

    NSTask+PTY.m

    #import "NSTask+PTY.h"
    #import <util.h>
    
    @implementation NSTask (PTY)
    
    - (NSFileHandle *)masterSideOfPTYOrError:(NSError *__autoreleasing *)error {
        int fdMaster, fdSlave;
        int rc = openpty(&fdMaster, &fdSlave, NULL, NULL, NULL);
        if (rc != 0) {
            if (error) {
                *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];
            }
            return NULL;
        }
        fcntl(fdMaster, F_SETFD, FD_CLOEXEC);
        fcntl(fdSlave, F_SETFD, FD_CLOEXEC);
        NSFileHandle *masterHandle = [[NSFileHandle alloc] initWithFileDescriptor:fdMaster closeOnDealloc:YES];
        NSFileHandle *slaveHandle = [[NSFileHandle alloc] initWithFileDescriptor:fdSlave closeOnDealloc:YES];
        self.standardInput = slaveHandle;
        self.standardOutput = slaveHandle;
        return masterHandle;
    }
    
    @end
    

    You can use it like this:

    NSTask *_currentTask = [[NSTask alloc] init];
    _currentTask.launchPath = @"/usr/bin/python";
    _currentTask.arguments = @[[[NSBundle mainBundle] pathForResource:@"nameTest" ofType:@"py"]];
    
    NSError *error;
    NSFileHandle *masterHandle = [_currentTask masterSideOfPTYOrError:&error];
    if (!masterHandle) {
        NSLog(@"error: could not set up PTY for task: %@", error);
        return;
    }
    

    Then you can read from the task and write to the task using masterHandle.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a simple python script that just takes in a filename, and spits
I have a simple Python script that uses a signal handler for Ctl-C. If
I have a simple Python script that uses the socket module to send a
I have a very simple python script that should scan a text file, which
I have the following simple python test script that uses Suds to call a
I have a python script on a vps that I run a simple command
I have a simple Python script that receives username and password as arguments, but
I have a rather simple Python script that contains a function call like f(var,
I have a simple python script that updates that statuses of justin.tv streams in
I have a simple python script that i wrote for IDA, but i'am can't

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.