mwilliamson / spur.py

Run commands and manipulate files locally or over SSH using the same interface
BSD 2-Clause "Simplified" License
267 stars 37 forks source link

Closing process stdin, stdout and stderr #23

Open niklasf opened 9 years ago

niklasf commented 9 years ago

Hi.

There seams to be no "official" way to close the standard input, output and error streams of a Spur process. A hack like

def close_std_streams(process):
    try:
        process._process_stdin.close() # Local
    except AttributeError:
        process._stdin.close() # SSH

    process._io._handlers[0]._file_in.close()
    process._io._handlers[1]._file_in.close()

appears to work, but is there a better way or should there be some method to do that?

Best regards Niklas

mwilliamson commented 9 years ago

Hello Niklas,

You're right in that this is a feature that I've not implemented, simply because it's not come up before. The simplest solution I can think of is to expose stdin, stdout and stderr attributes on the process object. Do you think calling close on any of them should call close any associated file objects? For instance, calling close on stdout should close stdout of the process, but should it also call close on any file objects hooked up to be piped from stdout?

niklasf commented 9 years ago

Hi Michael,

today I noticed that my above hack is not sufficient. IOError: close() called during concurrent operation on the same file object. because the handler thread is still reading the output stream.

I am not sure what would be best here, yet. For orientation I'll check how subprocess.Popen does this.

ninoles commented 8 years ago

Somewhat related, I end up adding a shutdown_write method on the SshProcess object, that call either the shutdown_write method on channel. I agree with @niklasf about looking at subprocess.Popen for the behavior.

ri0t commented 4 years ago

I was trying hard to get a public key from wireguard until i found out that it needs stdin closed to operate, their syntax to do that with pipes is thus: wg pubkey < secretkeyfile > publickeyfile ..which when running in a terminal only responds after "signaling" EOF on the input.

So, yeah, :+1: for adding a close operation for std*