How to pass commands to an SSH from subprocess in Python

岁酱吖の 提交于 2020-06-27 13:03:08

问题


I have used the subprocess module in Python 2.7.6 to establish an SSH. I realise that this is not recommended, but I am unable to install other Python SSH libraries such as paramiko and fabric.

I was just wondering if someone wouldn't mind just telling me how I'd now go about

sshProcess = subprocess.call(['ssh', '-t', '<REMOTE>', 'ssh', '<REMOTE>']) 

I want to carry out commands in REMOTE with the subprocess approach. Is there any way to do this? Unfortunately, REMOTE is protected by a password which the user manually enters. If it helps, I'm running the Windows 10 Bash shell.

Any help is appreciated.


回答1:


Running a remote command is as simple as putting it on the command line. (This is distinguishable to the SSH server at a protocol level from feeding it on stdin, but the protocol in question is built for programmatic use, vs built for human use -- as the latter was the design intent behind the interactive-shell model).

By the way, if you want to run multiple commands via distinct SSH invocations over a single connection after authenticating only once, I'd strongly suggest using Paramiko for this, but you can do it with OpenSSH command-line tools by using SSH multiplexing support.


Let's say you have an array representing your remote command:

myCommand = [ 'ls', '-l', '/tmp/my directory name with spaces' ]

To get that into a string (in a way that honors the spaces and can't let a maliciously-selected name run arbitrary commands on the remote server), you'd use:

myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)

Now, you have something you can pass as a command line argument to ssh:

subprocess.call(['ssh', '-t', hostname, myCommandStr])

However, let's say you want to nest this. You can just repeat the process:

myCommand = [ 'ssh', '-t', hostname1, myCommandStr ]
myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)
subprocess.call(['ssh', '-t', hostname2, myCommandStr])

Because we aren't redirecting stdin or stdout, they should still be pointed at the terminal from which your Python program was started, so SSH should be able to execute its password prompts directly.


That said, specifically for ssh'ing through an interim system, you don't need to go through this much trouble: You can tell ssh to do that work for you with the ProxyJump option:

myCommand = [ 'ls', '-l', '/tmp/my directory name with spaces' ]
myCommandStr = ' '.join(pipes.quote(n) for n in myCommand)
subprocess.call(['ssh', '-o', 'ProxyJump=%s' % hostname1, hostname2, myCommandStr])



回答2:


From your comment, you say you can connect. So after that, to interact over ssh using subprocess you will need something like:

ssh = subprocess.Popen(['ssh', <remote client>],
                           stdin=subprocess.PIPE, 
                           stdout = subprocess.PIPE)
back  = ssh.stdout.readlines()
if result == []:
    error = ssh.stderr.readlines()
    print error
else:
    print back

then to send commands, like list directory, something like:

ssh.stdin.write("ls\n")


来源:https://stackoverflow.com/questions/42815060/how-to-pass-commands-to-an-ssh-from-subprocess-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!