asyncssh icon indicating copy to clipboard operation
asyncssh copied to clipboard

Why is the loop waiting for command execution endless?

Open sh1man999 opened this issue 1 year ago • 1 comments

class BaseSSHClientSession(asyncssh.SSHClientSession):
    def __init__(self):
        self._stdin = None
        self._stdout = None
        self._stderr = None
        self._recv_ready = asyncio.Event()
        self._output_buffer = ""
        self._closed = asyncio.Event()
        self._eof_received = False

    def connection_made(self, chan):
        self._stdin = chan
        self._stdout = chan
        self._stderr = chan
        print("Connection made")

    def data_received(self, data, datatype):
        print(f"Data received: {data}")
        self._output_buffer += data
        self._recv_ready.set()

    def eof_received(self):
        print("EOF received")
        self._eof_received = True
        self._recv_ready.set()

    def connection_lost(self, exc):
        if exc:
            print(f'SSH session error: {exc}')
        else:
            print("SSH session closed")
        self._recv_ready.set()
        self._closed.set()

    async def run_command(self, command: str, timeout: Optional[int] = None) -> str:
        self._recv_ready.clear()
        self._output_buffer = ""
        self._eof_received = False
        self._stdin.write(command + '\n')
        print("Command sent")

        while not self._eof_received:
            try:
                await asyncio.wait_for(self._recv_ready.wait(), timeout)
                self._recv_ready.clear()
            except asyncio.TimeoutError:
                raise CommandSshException(f"Command '{command}' timed out")

        print("Command received")
        output = self._output_buffer
        self._output_buffer = ""
        return output
    **The problem is in this block of code**
        while not self._eof_received:
            try:
                await asyncio.wait_for(self._recv_ready.wait(), timeout)
                self._recv_ready.clear()
            except asyncio.TimeoutError:
                raise CommandSshException(f"Command '{command}' timed out")

sh1man999 avatar May 30 '24 12:05 sh1man999

You appear to be opening an interactive shell session and writing a command to stdin. However, you are waiting for EOF to be received. That'll never happen, as the server will simply go back and output the shell prompt after the command completes. It is up to you to find a way to know when the command has finished running and you're sitting back at a remote shell prompt again.

Since you are using callbacks, you'd have to parse the output coming in via data_received() to determine when the command output is done and it's time to send another command to the remote shell. Alternately, you could try sending something like "command" followed by "exit" in a single command (e.g. "command; exit"). That might cause the shell to exit, at which point you'd get the EOF you were expecting.

ronf avatar May 30 '24 12:05 ronf

Closing due to inactivity. Feel free to reopen this or open a new issue if you need anything else.

ronf avatar Jul 03 '24 15:07 ronf