2011-06-16 34 views
9

在我与我的教授的工作中,我必须ssh进入我们的服务器,然后从那里进入每个节点运行我们的程序。我正在尝试编写一个python程序,它可以让我在本地机器上完成所有需要在远程节点上执行的操作。我将在节点上运行的命令是:从本地机器通过中间主机的SSH到机器

  • CP文件到远程节点
  • 运行程序的每个节点上
  • 检索节点文件到我的本地机器
  • 也许可以复制fortran程序并在节点上编译它,并检查节点以查看是否有程序正在运行。

现在我在我的本地机器上创建我的输入文件,将它们传送到服务器,然后将文件复制到每个节点并在每个节点上运行我们的fluid_dynamics程序。然后我做相反的操作,让我们的输出回到我的本地机器。

我在看paramiko,但我无法弄清楚如何使用它从本地机器到节点,因为我必须通过服务器。 当地-ssh - >服务器-ssh - >节点

有没有办法在Python做到这一点还是我应该尝试其他的东西,如:使用 :

os.system(ssh -t server ssh node 'command') 

或制作一个bash为每个不同的命令(compile.sh,move_inputs.sh,retrieve_outputs.sh)服务器上的脚本,然后只连接到服务器并运行bash脚本。

对不起,如果这没有意义或如果措辞不妙,任何帮助表示赞赏。

附加信息: 我使用python的原因是因为我希望程序能够生成输入文件,将它们发送到节点并检索输出文件,并最终生成我们数据的图形。我已经有一些代码来生成我们的输入文件,并从输出中生成图形。

回答

7

你不需要Python来做到这一点。检查ProxyCommand configuration option for SSH。这是一个tutorial,它解释了细节。

+0

我会考虑这个。我使用python的原因是因为我希望程序能够制作输入文件,将它们发送到节点并检索输出文件,并最终生成我们数据的图形。我已经有一些代码来生成我们的输入文件,并从输出中生成图形。 – Russss 2011-06-16 03:24:32

+0

尽管我没有测试过它,但我确信即使您使用Python进行SSH,使用ProxyCommand的SSH配置也能正常工作。 – badzil 2011-06-16 04:57:14

5

用我的同事的一个技巧,你可以直接从本地到节点ssh/scp。

编辑你的〜/ .ssh /配置:

Host * 
ControlMaster auto 
ControlPath ~/.ssh/master-%[email protected]%h:%p 

Host node1 node2 or node* 
ProxyCommand ssh server 'nc -w 5 %h 22' 

玩得开心!

+0

我也是这样做的,但是ControlMaster方法有一些缺点。这是一个很好的总结:http://www.anchor.com.au/blog/2010/02/ssh-controlmaster-the-good-the-bad-the-ugly/ – Mzzzzzz 2012-02-05 21:40:14

3

你可以通过你的服务器节点创建隧道做到这一点:

import os, sys, shlex 
import subprocess 
import paramiko 

cmd = "ssh -f -N -p " + str(serverport) + " -l " + serveruser + " -L " + str(tunnelport) + ":" + nodehost + ":" + str(nodeport) + " " + serverhost 
args = shlex.split(cmd) 
tun = subprocess.Popen(args) 
stat = tun.poll() 

一旦隧道设置你可以ftp到节点:

transport = paramiko.Transport(("127.0.0.1", tunnelport)) 
transport.connect(username=nodeusername, password=nodepw) 
sftp = paramiko.SFTPClient.from_transport(transport) 
sftp.put(localfile, remotefile) 

或您可以使用paramiko.SSHClient()。connect(“127.0.0.1”,port = port,username = user,password = pw)和paramiko.SSHClient()。exec_command(command)来连接并执行命令。

然后在隧道过程可以这样被杀:

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE) 
out, err = p.communicate() 
for line in out.splitlines(): 
    if cmd in line: 
     pid = int(line.split(None, 1)[0]) 
     os.kill(pid, signal.SIGKILL) 
3

你可以用的paramiko做到这一点:

proxy_command = 'ssh -i %s %[email protected]%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) 

proxy = paramiko.ProxyCommand(proxy_command) 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect(host, username=user, password=password, sock=proxy) 

stdin, stdout, stderr = client.exec_command('echo HELLO') 
print "Echo: %s" % (", ".join(stdout.readlines())) 
client.close() 

它与SFTPClient太:

proxy_command = 'ssh -i %s %[email protected]%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) 

proxy = paramiko.ProxyCommand(proxy_command) 

transport = paramiko.Transport(proxy) 
transport.connect(username=user, password=password) 

sftp = paramiko.SFTPClient.from_transport(transport) 
相关问题