Pycharm remote interpreter over ssh doesn’t work too well on windows, with there not being a real ssh server available.

I’m using a linux local machine to debug an app on a remote windows one.

On Windows:

Install babun: http://babun.github.io/
Open babun prompt
>>
Install openssh, python

pact install openssh
pact install python

Enable ssh server, but don’t install as service

ssh-host-config

Copy in appropriate sshl login key

mkdir -p ~/.ssh
cat id_rsa.pub >> ~/.ssh/authorized_keys

Copy conin.exe into babun from http://mintty.googlecode.com/files/conin-0.0.2.zip

cp conin.exe %BABUN%\bin\

Copy in custom shell script

cat > "/bin/ssh_shell" << EOF
#!/usr/bin/python
import os
import sys
import logging
from subprocess import call, check_output

logger = logging.getLogger()
logger.setLevel(logging.INFO)
hdlr = logging.FileHandler('/tmp/ssh_shell.log')
hdlr2 = logging.StreamHandler()
hdlr.setLevel(logging.INFO)
hdlr2.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
hdlr2.setFormatter(formatter)
logger.addHandler(hdlr)
#logger.addHandler(hdlr2)

logger.info(sys.argv)
try:
    if len(sys.argv) == 1:
        call(['/bin/bash'])
    else:
        args = sys.argv[1:]
        if len(args) > 1 and 'JETBRAINS_REMOTE_RUN' in args[1]:
            import re
            cmds = args[1].split(" ")
            cd = ""
            if cmds[0] == 'cd':
                cd = "%s %s && " % (cmds.pop(False),
                                    check_output(['cygpath', '-w', cmds.pop(False)]).strip().rstrip(';'))

            envs = []
            idx = 0
            assert cmds[idx] == 'env', cmds[idx]
            for idx in range(1, len(cmds)):
                if "=" in cmds[idx]:
                    envs.append(cmds[idx].replace('"', ''))
                else:
                    break

            cmd = [check_output(['cygpath', '-w', c]).strip() if re.findall(r'^/[a-zA-Z]|cygdrive/', c) else c
                   for c in cmds[idx:]]
            env = " ".join(["set %s &&" % e for e in envs])

            cmd = '%s%s %s' % (cd, env, " ".join(cmd))
            cmd = ['/bin/conin', 'cmd', '/c', cmd]
            logger.warn(cmd)
            call(cmd)

        elif args[0] == '-c':
            call(['/bin/bash']+args)
except:
    logger.exception("syntax")

EOF

update the shell for the current user to custom script

sed -i "s:\($USER.*\)/bin/bash:\1/bin/ssh_shell:g" /etc/passwd

start sshd (as the login user) at startup

cat > "$APPDATA/Microsoft/Windows/Start Menu/Programs/Startup/sshd.bat" << EOF
set PATH=$(cygpath -w /bin);%PATH%
$(cygpath -w /usr/sbin/sshd)
EOF

On the linux machine, do a trial login to the remote pc

ssh user@hostname

and check it works, putting you in bash

if the remote files you’re debugging are on a mapped drive, remap it here

conin cmd /c "net use O: \\server\share <password> /persistent:yes /user:<user>"

if that command complains about multiple logins for a user, omit the final /user arg and try again

# On pycharm, on linux, start adding a remote python interpreter.
# Enter the hostname and appropriate login cert/password etc.
# Use windows paths for interpreter path and cygwin path for helpers path

C:\python27\python.exe
/C/users/<user>/.pycharm_helpers

Ignore the error about not being able to find the python path (it uses sftp to try to check it exists which expects cygwin path)
Press “Save Anyway”

Hit ok, pycharm should do it’s ‘Uploading PyCharm helpers…’ thing.