0

I'm working on a little python program to speed up managing various Raspberry Pi servers over SSH. It's all done but for one thing. Interacting with an SSH session isn't wokring the way I want it to.

I can interact with a command but some commands (specifically apt full-upgrade) which ask or have potential to ask questions whilst they're running aren't working. So when it reaches the point where it asks do you want to continue [Y/n] it falls over. I believe it's because apt can't read from the stdin so aborts.

I know I could run the apt command with the -y flag and bypass the question but ideally I'd like to be able to capture requests and ask the user for input. I've been using Paramiko to manage my SSH sessions and what I'm doing is capturing the stdout and passing it to the find function to look for things like [Y/n] and if it finds that then redirect the user to an input prompt which works but because theres no stdin when apt asks the question it aborts and when I send my user input back to the SSH session I get a socket closed error.

I've been looking for alternatives or ways to get round the issue but apart from seeing fabric mentioned as an alternative to paramiko I can't see a lot of other options out there. Does anyone know of any alternatives I can try to paramiko. I don't think fabric will work for me given its based off paramiko so I assume I'd hit the same error there. I'd appreciate any recoomendations or pointers if there's other parts of Paramiko I can try (I've stuck to using exec_command). I have tried channels which work to a point but I don't think keeping the SSH session open is the issue I think I need someway to keep stdin open/accessible to the apt command on the remote machine so it doesn't abort the command.

At the minute the best idea I've got to get round it is to run the command let it potentially abort look in stdout for the relevant phrases then run the command again after giving the user chance to set their inputs and pass the whole lot to stdin?

EDIT:

My program in steps:

  1. login to the remote host
  2. issue a command
  3. use .find on the command to check for the use of 'sudo'
  4. if sudo is present additionally send the user password to stdin along with the command
  5. read the stdout to check for keywords/phrases like '[Y/n]' which are present when the user is being asked for input when running a command
  6. if a keyword is found then ask the user for their input which can then be sent back to stdin to continue the command.

Steps 5 and 6 are where it fails and returns with a socket closed error. Looking online I don't think the issue is with paramiko as such but with the command running on the remote host. In my case sudo apt full-upgrade.

When I run that command it runs up to the 'Would you like to continue' point the automatically aborts, I believe the issue there is because there is nothing present in the stdin at that point (thats what I'm asking the user for) Apt automatically aborts

This is the part of my code where I'm running the commands:

            admin = issue_cmd.find('sudo')

        connect.connect(ip_addr, port, uname, passwd)
        stdin, stdout, stderr = connect.exec_command(issue_cmd, get_pty=True)

        if admin != -1:
            print('Sudo detected. Attempting to elevate privileges...')
            stdin.write(passwd + '\n')
            stdin.flush()
        else:
            continue

        output = stdout.read()
        search = str(output).find('[Y/n]')

        if search != -1:
            resp = input(': ')
            print(resp)
            stdin.write(resp + '\n')
            stdin.flush()
        else:
             pass

        print(stdout.read().decode('utf-8').strip("\n"))
        print(stderr.read().decode('utf-8').strip("\n"))

        connect.close()

and here's the error message I'm seeing:

OSError: Socket is closed
rohtua
  • 165
  • 1
  • 11
  • See [Running interactive commands in Paramiko](https://stackoverflow.com/q/373639/850848). – Martin Prikryl Mar 15 '20 at 15:01
  • @MartinPrikryl Hi, I've seen that post, I can interact with the commands but only if I send each interaction sequentially through paramiko alltogether. If I stop to ask the user for input then I get a closed socket error. I've looked at the paramiko demo files and they don't seem to be working for me. I just get an 'exception in thread-3' error – rohtua Mar 15 '20 at 15:13
  • I do not understand what you mean by *"If I stop to ask the user for input then I get a closed socket error"*. – If you have seen that post, you should have mentioned it in your question and you should have explained how did you try to implement it and what problems did you face. – Martin Prikryl Mar 15 '20 at 15:15
  • @MartinPrikryl I've edited the post with the code I've written. I didn't mention that I've seen that post because my question isn't really about how interact with a command using paramiko but about the error I'm seeing and any alternative ways I could issue SSH commands or stop the command from aborting if there's nothing waiting in stdin. – rohtua Mar 15 '20 at 15:42

0 Answers0