我是python的新手.我写了一个脚本来连接到主机并执行一个命令
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=pw)
print 'running remote command'
stdin, stdout, stderr = ssh.exec_command(command)
stdin.close()
for line in stdout.read().splitlines():
print '%s$: %s' % (host, line)
if outfile != None:
f_outfile.write("%s\n" %line)
for line in stderr.read().splitlines():
print '%s$: %s' % (host, line + "\n")
if outfile != None:
f_outfile.write("%s\n" %line)
ssh.close()
if outfile != None:
f_outfile.close()
print 'connection to %s closed' %host
except:
e = sys.exc_info()[1]
print '%s' %e
Run Code Online (Sandbox Code Playgroud)
当远程命令不需要tty时工作正常.我找到了一个与Paramiko 一起使用的invoke_shell示例嵌套SSH会话.我对这个解决方案不满意,因为如果服务器有一个未在我的脚本中指定的提示 - >无限循环或脚本中的指定提示是返回文本中的字符串 - >不会收到所有数据.是否有更好的解决方案,也许stdout和stderr像我的脚本一样发回?
我想编写一个程序(在Windows 7上的Python 3.x中),它通过ssh在远程shell上执行多个命令.在查看了paramikos的exec_command()函数之后,我意识到它不适合我的用例(因为在执行命令后通道被关闭),因为命令依赖于环境变量(由先前的命令设置)而不能连接到一个exec_command()调用,因为它们将在程序中的不同时间执行.
因此,我想在同一个通道中执行命令.我研究的下一个选项是使用paramikos的invoke_shell()函数实现交互式shell:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=psw, port=22)
channel = ssh.invoke_shell()
out = channel.recv(9999)
channel.send('cd mivne_final\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd or_fail\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd simulator\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
ssh.close()
Run Code Online (Sandbox Code Playgroud)
这段代码存在一些问题:
我对这种"非决定论"感到困惑,非常感谢你的帮助.
创建从REMOTE到PROXY的ssh连接,以将REMOTE计算机上端口22上的ssh流量转发到PROXY服务器上的端口8000.
#从REMOTE机器运行
ssh -N -R 0.0.0.0:8000:localhost:22 PROXY_USER @ PROXY_HOSTNAME
创建一个从LOCAL到PROXY的ssh隧道,并将来自LOCAL:1234的ssh流量转发到PROXY:8000(然后转发到REMOTE:22).
#从LOCAL机器运行
ssh -L 1234:localhost:8000 PROXY_USER @ PROXY_HOSTNAME
创建从LOCAL到REMOTE的转发ssh连接(通过PROXY).
#在新的终端窗口中从LOCAL机器运行
ssh -p 1234 REMOTE_USER @ localhost#我现在已经转到REMOTE框并可以运行命令
我查看了一些与使用Paramiko进行端口转发相关的问题,但它们似乎并未解决这种特定情况.
如何使用Paramiko运行上面的步骤2和3?我基本上想运行:
import paramiko
# Create the tunnel connection
tunnel_cli = paramiko.SSHClient()
tunnel_cli.connect(PROXY_HOSTNAME, PROXY_PORT, PROXY_USER)
# Create the forwarded connection and issue commands from LOCAL on the REMOTE box
fwd_cli = paramiko.SSHClient()
fwd_cli.connect('localhost', LOCAL_PORT, REMOTE_USER)
fwd_cli.exec_command('pwd')
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Paramiko编写部署脚本,而我在运行的命令中遇到退出代码时遇到问题.我正在使用与此答案类似的代码,但它有点复杂.基本上,从我们的开发盒中,我们必须通过跳转服务器,并从那里到一系列生产机器.在那里,我们必须切换到系统用户(sudo su - systemuser)然后我们可以运行命令.
问题是,据我所知,我有3个子shell - ssh会话,嵌套的ssh命令,然后是su subshell.我不能让Paramiko给我回到内部子shell中命令的退出代码 - 我猜它最终将返回的退出代码将是ssh命令的退出代码.我怀疑这个问题实际上并不是Paramiko特有的 - SSH协议是否支持这种用法?
我目前总是执行:
(my command); echo "Process terminated with exit code $?"
Run Code Online (Sandbox Code Playgroud)
然后在客户端解析这个,但它很丑 - 有更好的方法吗?
我有一个托管在 Amazon RDS(“D”)上的远程 MySQL 数据库。出于安全目的,它只能通过远程服务器(“C”)访问。C 可通过跳转主机“B”通过 ssh 访问。我需要一个双 ssh 隧道来访问远程 SQL 主机。
[A: local host] -> [B: jump host] -> [C: target host] => [D: RDS MySQL host]
Run Code Online (Sandbox Code Playgroud)
我想通过 Python 访问 D,使用 paramiko 和/或 sshtunnel。我能找到的所有信息都涉及: