Setheron
Setheron

Reputation: 3740

Python Windows7: Odd behaviour opening file for append

I am seeing odd behaviour when I open a file in append mode ('a+') under Windows 7 using Python.

I was wondering whether the behaviour is in fact incorrect or I am misunderstanding how to use the following code:

log_file= open(log_file_path, "a+")
return_code = subprocess.call(["make", target], stdout=log_file, stderr=subprocess.STDOUT)
log_file.close()

The above code lines does not properly append to the file. In fact on subsequent runs it won't even modify the file. I tested it out using the Python Shell as well. Once the file has been opened for the first time, making multiple subprocess calls will append properly to the file, however once the file has been closed and reopened it will never append again.

Anyone have any clues?

Thanks


To further simply the problem Here is another set of steps that will fail:

log_file=open("temp.txt", "a+")
log_file.write("THIS IS A TEST")
log_file.close()
log_file=open("temp.txt", "a+")
subprocess.call(["echo", "test"], stdout=log_file, stderr=subprocess.STDOUT, shell=True)
log_file.close()

If you open the file temp.txt here is what I see:

test
S A MUTHER F** TEST

Upvotes: 2

Views: 219

Answers (2)

jschlag
jschlag

Reputation: 11

see http://mail.python.org/pipermail/python-list/2009-October/1221841.html

briefly: opening a file in append mode leaves the file ptr in an implementation-dependent state. seek to the end to get the same results on windows as on linux.

Upvotes: 1

JoeFish
JoeFish

Reputation: 3100

It looks like your problem is in the use of shell=True. From Python documentation for POpen:

On Unix, with shell=True: If args is a string, it specifies the command string to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.

So it looks like "echo" is the command, and "test" gets sent as an argument to the shell, instead of to "echo".

So changing your subprocess call to either:

subprocess.call("echo test", stdout=log_file, stderr=subprocess.STDOUT, shell=True)

or:

subprocess.call(["echo", "test"], stdout=log_file, stderr=subprocess.STDOUT)

Fixes the problem, at least in my testing.

Upvotes: 1

Related Questions