Reputation: 3474
I have a shell program that needs to be pointed at a text file. I would like to write to a temporary file, run this program on it via Python's subprocess method, and save the output. Here's what I have so far:
with open('test.txt', 'w') as f:
for i in range(50):
f.write('sometext %d'%i)
f.flush()
output = subprocess.check_output('./program test.txt', shell=True, stderr=subprocess.STDOUT)
Output only gets updated once. I'm assuming that flush
isn't able to write to the file before the next iteration of the loop executes. What other ways could this be implemented? Opening and closing the file seems like it would be expensive, because this code is going to be called many times.
Upvotes: 0
Views: 175
Reputation: 87084
I'm pretty sure that you realise that output
is rebound on each iteration, and will therefore contain only the final value at the end, so I've tried a slightly modified version of your code and found that it works as expected.
output = []
with open('test.txt', 'w') as f:
for i in range(20):
f.write('%d ' % i)
f.flush()
output.append(subprocess.check_output('cat test.txt', shell=True, stderr=subprocess.STDOUT))
>>> from pprint import pprint
>>> pprint(output)
[b'0 ',
b'0 1 ',
b'0 1 2 ',
b'0 1 2 3 ',
b'0 1 2 3 4 ',
b'0 1 2 3 4 5 ',
b'0 1 2 3 4 5 6 ',
b'0 1 2 3 4 5 6 7 ',
b'0 1 2 3 4 5 6 7 8 ',
b'0 1 2 3 4 5 6 7 8 9 ',
b'0 1 2 3 4 5 6 7 8 9 10 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ',
b'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ']
Upvotes: 0
Reputation: 91049
If you want to omit closing and re-opening (which would probably be the cleanest way), you might want to f.seek(0)
at the start and f.truncate()
after writing.
Otherwise, the data is appended to the file on every loop run and the external program might be confused.
Upvotes: 1
Reputation: 955
You may need to call os.fsync()
as well to make sure that the changes are not just flushed but forcefully written to disk as well.
Upvotes: 0
Reputation: 6510
f.flush
will not definitely write to disk, if buffer isn't filled.
Upvotes: 0