0

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)
bgoodr
  • 2,744
  • 1
  • 30
  • 51
  • `f.flush()` is correct. `f.seek()` happens to flush as an extra side effect, but that's not its primary purpose. – Barmar Feb 04 '23 at 22:52
  • Okay, that's what I thought. If you post an answer, I will mark it as the answer. Thank you. – bgoodr Feb 09 '23 at 02:09

1 Answers1

1

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.

Barmar
  • 741,623
  • 53
  • 500
  • 612