6

I'm running a script to manage processes on a remote (SSH) machine. Let's call it five.py

#!/usr/bin/python
import time, subprocess

subprocess.call('echo 0',shell=True)
for i in range(1,5):
   time.sleep(1)
   print(i)

If i now run

ssh user@host five.py

I would like to see the output

0
1
2
3
4

appear on my standard out second by second (as it does if execute locally).. What happens is: I get the 0 from "echo" right away and the rest only appears at once after the entire program finishes. (Doesn't help to nest 'five.py' into a bash script; to call it by 'python five.py'; or to use 'print >> sys.stdout, i').

This must be related to the way python writes to stdout, since other programs behave quite normal.. A functional workaround is

import time, subprocess
import sys

subprocess.call('echo 0',shell=True)
for i in range(1,5):
  time.sleep(1)
  sys.stdout.write(str(i)+'\n')
  sys.stdout.flush()

But there must be a better solution than changing all my print statements!

3 Answers 3

7

You can add the -u on the shebang line as interjay hinted

#!/usr/bin/python -u

You could also reopen stdout with buffering turned off or set to line buffering

import os,sys
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) # no buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1) # line buffering

Usually line buffering is a good choice

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot: 'sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)' works very well and should be more secure than 'python -u'
0

You can replace the sys.stdout object so that it automatically flushes after each write. This will also affect the print statement. An example, taken from this answer:

class flushfile(object):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

Edit: Another option is to start Python with the -u option, which will force input and output to be unbuffered.

Comments

0

One thing you might look at using since you are already using Python is Paramiko, much nicer way to do remote SSH work. Here is an article about how I am using it in its most basic form.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.