#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u  # python2.x中不需要这一行

default_username = getpass.getuser()
username = input('Username [%s]: ' % default_username)
if len(username) == 0:
    username = default_username

hostname = input('Hostname: ')
if len(hostname) == 0:
    print('*** Hostname required.')
    sys.exit(1)

tran = paramiko.Transport((hostname, 22,))
tran.start_client()

default_auth = "p"
auth = input('Auth by (p)assword or (r)sa key[%s] ' % default_auth)
if len(auth) == 0:
    auth = default_auth

if auth == 'r':
    default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
    path = input('RSA key [%s]: ' % default_path)
    if len(path) == 0:
        path = default_path
    try:
        key = paramiko.RSAKey.from_private_key_file(path)
    except paramiko.PasswordRequiredException:
        password = getpass.getpass('RSA key password: ')
        key = paramiko.RSAKey.from_private_key_file(path, password)
    tran.auth_publickey(username, key)
else:
    pw = getpass.getpass('Password for %s@%s: ' % (username, hostname))
    tran.auth_password(username, pw)

# 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell()

while True:
    # 监视用户输入和服务器返回数据
    # sys.stdin 处理用户输入
    # chan 是之前创建的通道,用于接收服务器返回信息
    # select模块是IO多路复用模块,功能强大,无处不在,你值得学习和记忆!
    readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    if chan in readable:
        try:
            x = u(chan.recv(1024))  # python2.x中直接接收就可以,不要u
            if len(x) == 0:
                print('\r\n*** EOF\r\n')
                break
            sys.stdout.write(x)
            sys.stdout.flush()
        except socket.timeout:
            pass
    if sys.stdin in readable:
        inp = sys.stdin.readline()    # 一行一行的读取用户在终端输入的命令
        chan.sendall(inp)

chan.close()
tran.close()