Search code examples
pythonsubprocessexecute

How to write to a tempfile then execute it as a subprocess in Python?


I want to write to a file, then execute it as a subprocess. However, writing to the file normally then executing it results in the subprocess.run() call failing with OSError: [Errno 26] Text file busy: /tmp/<filename>. I'm running this on Linux. A minimal example is (imports+shebang removed for readability, otherwise this is the whole file):

def chmod_plus_x(file_path: str) -> None:
    st = os.stat(file_path)
    os.chmod(file_path, st.st_mode | stat.S_IEXEC)

try:
    script = tempfile.NamedTemporaryFile(delete=False)
    f = open(script.name, "w")
    f.write("ls /")
    f.flush()
    f.close()
    chmod_plus_x(script.name)

    subprocess.run(script.name, shell=False)
finally:
    os.remove(script.name)

I am aware with open(...) is better code, but it results in the same error, and for the sake of the question I'm trying to be explicit about the file being closed. As I understand it, this error is raised when an executable attempts to be simultaneously executed and open for writing, but the file is definitely not open at the time of execution. Or at least, it shouldn't be. Why is the file still open?


Solution

  • NamedTemporaryFile returns a file like object, which contains a handle to the opened file. So the error message is correct: the file is still open.

    You should directly write to script and above all close it before trying to run it:

    ...
    try:
        script = tempfile.NamedTemporaryFile(delete=False)
        script.write("ls /")
        script.flush()
        script.close()
        chmod_plus_x(script.name)
    
        subprocess.run(script.name, shell=False)
    finally:
        os.remove(script.name)
    ...