2013-05-11 63 views
5

我想從遠程機器上使用rsync和SSH(從Python程序中)獲取文件。rsync over ssh - 使用由Python中的Paramiko創建的通道

如何啓動rsync的本地實例並將其引入到我用Paramiko打開的SSH通道中?

+0

好從這裏開始我確實相信: http://unix.stackexchange.com/questions/48632/cant-share-an-ssh-connection-with-rsync – 2013-05-31 07:47:37

+0

你真的需要rsync的?我已經實現了一個簡單的替代方案,它檢查SFTP上的修改時間並上傳文件,如果你的主機有更新的文件:https://github.com/myaut/tsload/blob/master/agent/tools/buildsvc.py#L17 – myaut 2015-04-24 14:44:23

回答

0

我有paramiko和rsync的問題,我無法解決。我經常成功地使用的paramiko與其他一些命令(例如MKDIR,mpstat的,服務,本地Python程序等),使用這種典型框架:

client = paramiko.SSHClient() 
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    client.connect(domain, username="root",timeout=5) 

    stdin, mpstat, stderr = client.exec_command('mpstat') 
    x=mpstat.readlines() 
    # process the lines as though it is a file 

對於rsync的,而不是追求的paramiko解決方案,我回復到:

x='''ssh [email protected]%s "rsync -aRzq [email protected]%s:%s /root/Backups/%s/%s " \ 
     '''%(BackupServerIP, ServerIP, file, Service, Server) 
    os.system(x) 

我一般喜歡的paramiko因爲它很容易處理其輸出,所以我很想知道是否有使用它與rsync的問題,或者我只是不堅持足夠長的時間。

3

這是一個老問題,但仍然是Google在搜索「rsync over paramiko」時的第一次打擊,並且這裏唯一上一個投票項目是與OP的問題無關的評論(該評論中的鏈接點使用Paramiko不支持的ControlMaster)。

有一個示例說明如何在Paramiko演示here之一中設置本地端口轉發。在pull request中還有一個易於使用的版本。使用ssh協議

  1. 正向一個特設的本地端口到遠程SSH服務器和rsync在本地端口:您可以使用本地端口轉發兩種方式。這相當於運行ssh -L12345:localhost:22 remote-host,然後是rsync --rsh 'ssh -p 12345' sourcedir/file localhost:/destdir/file
  2. 使用rsync協議通過本地端口將ad-hoc本地端口轉發到ad-hoc遠程rsync守護程序,並轉發rsync。這與運行ssh -L12345:localhost:12345後跟rsync sourcedir/file rsync://localhost:12345/module/destdir/file類似,不同之處在於您需要設置在12345上運行的ad-hoc rsync守護程序,其模塊名稱指向遠程主機上的destdir

我個人比較喜歡第二個方法上面,雖然它是稍微複雜一點,因爲它跳過了本地ssh客戶端,並且也使用rsync的協議,我認爲這是比使用ssh更有效。

從上面拉請求使用ForwardServer,代碼看起來有點像這樣(取決於Fabric):

RSYNC_SPEC = """ 
port=12345 
use chroot=false 

[homedir] 
log file=/tmp/rsync-ad-hoc.log 
max verbosity=4 
path=/home/{user}/ 
read only=false 
""" 

@task 
def rsync(local_path, remote_path): 
    """ 
    local_path: Absolute path to a local source 
    remote_path: Relative path (from home directory) to a remote destination 
    """ 
    with ForwardServer(0, "localhost", rsync_port, connections[env.host_string].get_transport()) as serv: 
     local_port = serv.socket.getsockname()[1] 
     run("killall rsync; rm -f /tmp/rsync-ad-hoc.log /tmp/rsync-ad-hoc.conf; :") 
     put(local_path=StringIO(RSYNC_SPEC.format(user=env.user)), remote_path="/tmp/rsync-ad-hoc.conf",) 
     run("rsync --daemon --config /tmp/rsync-ad-hoc.conf") 
     remote_rsync_path = os.path.join("rsync://localhost:%s/homedir" % local_port, remote_path) 
     # Rsync expects the root of the destination to exist. 
     run("mkdir -p /home/{user}/{path}".format(user=env.user, path=remote_path)) 
     logging.info("Attempting rsync from (localhost, %s, %s) to (%s, %s, %s)", local_port, local_path, env.host_string, rsync_port, remote_path) 
     local("rsync -avzPh --delete %s/ %s/" % (local_path, remote_rsync_path)) 

您也可以具備的功能需要一個遠程的絕對路徑,並生成該目錄模塊(而不是假定它是相對於用戶的主目錄)。