0

From Windows (Windows 10, Python3.6.3) I would like to send a few simple command to a Linux server and get the results back. Nothing more. I want to keep it simple and short. I didn't expect this to be so difficult but there seems to be a mess of helpful-meant but non-working, outdated or too complicated solutions. I know, one shouldn't pass the password in the command line but I'm in a closed environment so I don't need advanced encryption and public/private keys, etc. I also know that People strongly recommend to use Paramiko, but for different reasons I cannot install.

My learnings so far:

  • pxssh does not work for Windows
  • PuTTY doesn't allow sending password in command line (whereas plink does)
  • people strongly recommend to use Paramiko. Although for different reasons I cannot install.
  • Fabric builds on Paramiko
  • I tried with ssh.exe without success

I guess, it doesn't make sense to list all the links of code snippets which did not work for me, there are too many... The following StackOverflow answers to these questions are either outdated or not helpful as well:

Currently, I think I am the closest with plink because in Windows command line, the following

C:\Users\Downloads\PuTTY\plink.exe -ssh -batch user@111.22.33.44 -pw abc123

directly logs in without entering a password manually or confirmation via pressing Enter, and I can manually type commands like ls, uname -a, etc.

Now, however, I want to do this programmatically via a Python program. Starting from here: https://stackoverflow.com/a/32615977/7295599 (which seems to be outdated). So far, I ended up with the following:

import subprocess

ffname_exe = r'C:\Users\Downloads\PuTTY\plink.exe'
user='user'
server='111.22.33.44'
password = 'abc123'
plink = '{} -ssh -batch {}@{} -pw {}'.format(ffname_exe, user, server, password)
print(plink)
proc = subprocess.Popen(plink, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

command='uname -a'
stdout, stderr = proc.communicate(command.encode(),timeout=10)
print(stdout)
print(stderr)

But this times out after 10 seconds without any result printed.

I'm not sure whether this a problem with subprocess or with plink or the server? Actually, I'm not bound to plink, any other simple solution on Windows using PuTTY,ssh.exe, etc. without user interaction (to type a password or confirm anything) and installation of Paramiko are fine.

theozh
  • 22,244
  • 5
  • 28
  • 72
  • 1
    You should use `plink.exe -ssh -batch user@111.22.33.44 -pw abc123 uname -a`. + If you want to keep using your `communicate` approach, you are missing `\n` to submit the command. Check your 3rd link: [Using Plink (PuTTy) to SSH through Python](https://stackoverflow.com/q/8067979/850848#8068239). – Martin Prikryl Jan 27 '21 at 15:55
  • @MartinPrikryl thanks. If I add `cmd = 'uname -a'` and modify `plink = '{} -ssh -batch {}@{} -pw {} {}'.format(ffname_exe, user, server, password, cmd)` I get some response. Great! However, then what do I need the line `command='uname -a'` for? I thought the actual commands are sent by `proc.communicate(command.encode(),timeout=10)`? Probably, I misunderstood something there?! – theozh Jan 27 '21 at 16:12
  • There are three ways to provide commands to plink. 1) On commandline: `plink user@host command` 2) Using `-m` switch and command file: `plink -m command.txt user@host` 3) By writing them to Plink input. – There are some differences between all three. – Martin Prikryl Jan 27 '21 at 16:17
  • @MartinPrikryl ok, where do I put the actual command into `Popen()` or in `communicate()`? So far only your 1) seems to work for me. If I want to send several separate commands, e.g. in a loop, do I have to create each time a new subprocess? I don't hope so. Could you please put the modified minimal example into an answer such that I can upvote and accept? – theozh Jan 27 '21 at 16:31
  • For `communicate`, I believe you need `command='uname -a\n'`. – Martin Prikryl Jan 27 '21 at 16:34

0 Answers0