我编写了一个脚本来建立SSH隧道并通过该隧道连接到数据库。在
极为简化的概要(省略了明显的参数和额外的逻辑):sshTunnelCmd = "ssh -N -p %s -L %s:127.0.0.1:%s -i %s %s@%s" % (
sshport, localport, remoteport, identityfile, user, server
)
args = shlex.split(sshTunnelCmd)
tunnel = subprocess.Popen(args)
time.sleep(2)
con = MySQLdb.connect(host="127.0.0.1", port=localport, user=user, passwd=pw, db=db)
## DO THE STUFF ##
con.close()
tunnel.kill()
下面是shell的等效命令,我测试了这些命令和脚本在“干净的客户端”条件下(即重新启动后)工作。在
^{pr2}$
SSH登录带有密钥,在~/.SSH/config中,服务器配置为Host server
Hostname F.Q.D.N
Port 22
User user
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist 600
IdentityFile ~/.ssh/id_rsa
在#######################。如果出现异常,它将要求手动输入根凭据,创建常规用户并继续执行这些操作(普通查询,所有这些都是手动测试的,并且在干净的客户端条件下使用python代码)。在ruz = raw_input('root user? ')
print (ruz)
rup = raw_input('root password? ')
print (rup)
print ("Root connecting to database.")
try:
cxroot = MySQLdb.connect(host=host, port=port, user=ruz, passwd=rup)
cur = cxroot.cursor()
except MySQLdb.Error, e:
print ("Root failed, sorry.")
print "Error %d: %s" % (e.args[0],e.args[1])
print ("GAME OVER.")
return -1
在clean client下,第一个和一些后续的执行都很好,包括当我尝试测试脚本的健壮性并删除用户服务器端时。但是,在某个时刻,它会以一种奇怪的方式挂起在上面代码块中的第二个原始输入之后。输出:root user? root
root
root password? s3cReTsTr1n9
-bash: line 1: s3cReTsTr1n9: command not found
此时,我唯一能做的就是终止进程或按CTRL+C,然后进行以下回溯:^CTraceback (most recent call last):
File "./initdb.py", line 571, in
main()
File "./initdb.py", line 526, in main
connection = connectDB ('127.0.0.1', localport, dbuser, dbpw, db)
File "./initdb.py", line 128, in connectDB
rup = raw_input('root password? ')
keyboardInterrupt
我注意到的另一个意外现象是,输入到终端窗口的键盘输入(我在Xubuntu 14.04LTS中的bash终端中运行这个功能)变得毫无反应,,所以我必须关闭终端选项卡并启动一个新的选项卡。这将清除键盘输入,但不清除脚本行为。在
我试图寻找一个解决方案,但通常的搜索引擎对我的情况没有帮助,可能是因为我不完全了解发生了什么。我怀疑键盘输入以某种方式被重定向到一个进程,可能是隧道子进程,但我无法解释为什么第一个原始输入正常工作,第二个却不能。在
我也对我创建隧道的方式感到不安,因此欢迎任何有关创建更强大隧道的建议。具体地说,我希望对隧道的创建有更细粒度的控制,而不是等待任意两秒钟来建立隧道,因为我没有来自该子进程的反馈。在
感谢您分享您的时间和专业知识。在