如何使用Fabric将目录复制到远程机器?

82 投票
3 回答
73386 浏览
提问于 2025-04-16 13:44

我在本地电脑上有一个文件夹,我想把它复制到远程电脑上,并且还想给它改个名字。我知道可以用 put() 来复制文件,但文件夹该怎么复制呢?我知道用scp很简单,但我更希望能在我的 fabfile.py 文件里完成这个操作。

3 个回答

28

对于使用 Fabric 2 的朋友们,put 现在只能上传文件,不能上传文件夹了。此外,rsync_project 也不再是 Fabric 主包的一部分。contrib 包已经被移除,具体情况可以在这里查看。现在,rsync_project 被改名为 rsync,而且你需要安装一个额外的包才能使用它:

pip install patchwork

假设你已经和你的服务器建立了连接:

cxn = fabric.Connection('username@server:22')

你可以像下面这样使用 rsync

import patchwork.transfers
patchwork.transfers.rsync(cxn, '/my/local/dir', target, exclude='.git')

更多信息请参考 fabric-patchwork 文档

33

我还会看看Project Tools模块:fabric.contrib.project 文档链接

这个模块里有一个叫upload_project的功能,它可以让你指定一个源目录和一个目标目录。更棒的是,还有一个rsync_project的功能,它使用rsync工具。这个功能很不错,因为它只会更新那些有变化的文件,并且可以接受一些额外的参数,比如“exclude”,这对于排除像.git这样的目录非常有用。

举个例子:

from fabric.contrib.project import rsync_project

def _deploy_ec2(loc):

    rsync_project(local_dir=loc, remote_dir='/var/www', exclude='.git')
115

你可以用 put 来实现这个功能(至少在 1.0.0 版本中是这样):

local_path 可以是一个相对路径或绝对路径的本地文件,或者是一个目录路径,并且可以包含类似于命令行的通配符,这些通配符是 Python 的glob模块可以理解的。同时,也会进行波浪号扩展(这是由 os.path.expanduser 实现的)。

详细信息请查看: http://docs.fabfile.org/en/1.0.0/api/core/operations.html#fabric.operations.put


更新:这个例子在 1.0.0 版本中运行得很好(对我来说):

from fabric.api import env
from fabric.operations import run, put

env.hosts = ['frodo@middleearth.com']

def copy():
    # make sure the directory is there!
    run('mkdir -p /home/frodo/tmp')

    # our local 'testdirectory' - it may contain files or subdirectories ...
    put('testdirectory', '/home/frodo/tmp')

# [frodo@middleearth.com] Executing task 'copy'
# [frodo@middleearth.com] run: mkdir -p /home/frodo/tmp
# [frodo@middleearth.com] put: testdirectory/HELLO -> \
#     /home/frodo/tmp/testdirectory/HELLO
# [frodo@middleearth.com] put: testdirectory/WORLD -> \
#     /home/frodo/tmp/testdirectory/WORLD
# ...

撰写回答