Below is a example script to generate a Bash script into a temporary file, execute it, allow stdout and stderr to be emitted to the stdout of the calling script, and automatically delete the file.
When I set use_fix = True
as stated below, and set use_seek
to either True
or False
, the script works: I see output. But if I set use_fix = False
, it does not work.
My question is this: Under the case of use_fix = True
, which setting of use_seek
is correct? More interestingly, why would I prefer one value over the other? My gut tells me that f.flush()
is correct, because that is what I think is required: The buffered I/O needs to be flushed to disk before the subsequent child process can open that script and execute it. Could it be that the seek is also forcing a flush, as a side-effect?
import tempfile
use_fix = True
use_seek = False
# use_seek = True
# Create a temporary file with a bash script
with tempfile.NamedTemporaryFile(prefix="/tmp/xxx.out.", suffix=".sh", mode='w+t', delete=True) as f:
f.write("#!/bin/bash\necho 'This is a temporary bash script'\necho 'error message' >&2")
if use_fix:
# Allow subprocess.run to "see" the temporary file contents on disk:
if use_seek:
f.seek(0)
else:
# Allow subprocess.run to "see" the output.
f.flush()
# Execute the bash script and capture its standard output and standard error
result = subprocess.run(["bash", f.name], stdout=sys.stdout, stderr=subprocess.STDOUT)
You should just use f.flush()
if you only need to flush output. You would use f.seek()
if you want to overwrite what you just wrote; the fact that it flushes is just an extra side effect. But it's not documented as far as I can tell, so you shouldn't rely on it.
According to Does Python automatically flush its buffer when calling seek and/or read operations following a write? CPython only flushes the buffer when you use SEEK_END
, I'm not sure why you're seeing the flush when you use SEEK_SET
.