Skip to main content

上下文管理器

用于 with 语句的上下文管理器。

注解

当使用Python 2.5时,您需要使用 from __future__ import with_statement 启动fabfile,以便使用 with 语句(这是Python 2.6+的常规非 __future__ 功能)。

注解

如果您使用多个直接嵌套的 with 语句,可以方便地在一个语句中使用多个上下文表达式。而不是写作:

with cd('/path/to/app'):
    with prefix('workon myvenv'):
        run('./manage.py syncdb')
        run('./manage.py loaddata myfixture')

你可以写:

with cd('/path/to/app'), prefix('workon myvenv'):
    run('./manage.py syncdb')
    run('./manage.py loaddata myfixture')

注意,你需要Python 2.7+才能工作。在Python 2.5或2.6上,您可以执行以下操作:

from contextlib import nested

with nested(cd('/path/to/app'), prefix('workon myvenv')):
    ...

最后,请注意,settings 实现 nested 本身 - 有关详细信息,请参阅其API文档。

fabric.context_managers.cd(path)

上下文管理器,在调用远程操作时保持目录状态。

在包装的块中对 runsudogetput 的任何调用将隐含地具有类似于 "cd <path> && " 前缀的字符串,以便给出涉及实际有状态的意义。

注解

cd 只影响 remote 路径 - 修改 local 路径,使用 lcd

因为 cd 的使用影响所有这样的调用,所以使用这些操作的任何代码,例如 contrib 节的大部分,也将受到使用 cd 的影响。

像实际的’cd’shell内置函数,cd 可以用相对路径调用(请记住你的默认开始目录是你的远程用户的 $HOME),也可以嵌套。

下面是一个“正常”尝试使用shell’cd’,这不工作,因为如何实现无壳SSH连接 - 状态是 保持之间的 runsudo 的调用:

run('cd /var/www')
run('ls')

上面的代码段将列出远程用户的 $HOME 的内容,而不是 /var/www。但是,使用 cd,它将按预期工作:

with cd('/var/www'):
    run('ls') # Turns into "cd /var/www && ls"

最后,演示(参见内嵌注释)的嵌套:

with cd('/var/www'):
    run('ls') # cd /var/www && ls
    with cd('website1'):
        run('ls') # cd /var/www/website1 && ls

注解

此上下文管理器当前通过附加(并且一如既往地恢复)环境变量 env.cwd 的当前值来实现。但是,这种实现可能会在将来更改,因此我们不建议手动更改 env.cwd - 只有 cdbehavior 将有任何向后兼容性的保证。

注解

空格字符将被自动转义以使处理这种目录名称更容易。

在 1.0 版更改: 除了命令运行操作之外,还适用于 getput

参见

lcd

fabric.context_managers.char_buffered(*args, **kwds)

强制本地端子 pipe 是字符,不是线,缓冲。

仅适用于基于Unix的系统;在Windows上,这是一个无操作。

fabric.context_managers.hide(*args, **kwds)

用于将给定输出 groups 设置为False的上下文管理器。

groups 必须是一个或多个字符串,用于命名在 output 中定义的输出组。给定的组将在封闭块的持续时间内设置为False,然后恢复为之前的值。

例如,为了隐藏“[hostname] run:”状态行,以及防止打印stdout和stderr,可以使用 hide 如下:

def my_task():
    with hide('running', 'stdout', 'stderr'):
        run('ls /var/www')
fabric.context_managers.lcd(path)

更新本地当前工作目录的上下文管理器。

这个上下文管理器与 cd 相同,除了它改变一个不同的env var(lcwd,而不是 cwd),因此只影响 local 的调用和 get/put 的局部参数。

相对路径参数是相对于本地用户的当前工作目录,这将取决于Fabric(或Fabric使用代码)被调用的位置。你可以检查这是与 os.getcwd。相对于使用中的fabfile的位置来固定事物可能是有用的,这可以在 env.real_fabfile 中找到

1.0 新版功能.

fabric.context_managers.path(path, behavior='append')

将给定的 path 附加到用于执行任何包装命令的PATH。

对包装块中的 runsudo 的任何调用将隐含地具有类似于在给定命令之前预先放置的 "PATH=$PATH:<path> " 的字符串。

您可以通过指定可选的 behavior 关键字参数来自定义 path 的行为,如下所示:

  • 'append':将给定路径附加到当前 $PATH,例如。 PATH=$PATH:<path>。这是默认行为。

  • 'prepend':在当前 $PATH 的前面给定路径,例如。 PATH=<path>:$PATH

  • 'replace':完全忽略 $PATH 的先前值,例如。 PATH=<path>

注解

这个上下文管理器目前是通过修改(以及随时恢复)环境变量 env.pathenv.path_behavior 的当前值来实现的。但是,此实施可能会在将来更改,因此我们不建议直接手动更改它们。

1.0 新版功能.

fabric.context_managers.prefix(command)

使用给定命令加 && 前缀所有包装的 run/sudo 命令。

这与 cd 几乎相同,除了嵌套调用附加到命令字符串列表,而不是修改单个字符串。

大多数时候,你会想要使用这个旁边的shell脚本来改变shell状态,例如导出或改变shell环境变量。

例如,该工具最常见的用途之一是使用来自 virtualenvwrapperworkon 命令:

with prefix('workon myvenv'):
    run('./manage.py syncdb')

在上面的代码段中,实际的shell命令运行将是这样:

$ workon myvenv && ./manage.py syncdb

此上下文管理器与 cd 兼容,因此如果您的virtualenv在其 postactivate 脚本中不是 cd,则可以执行以下操作:

with cd('/path/to/app'):
    with prefix('workon myvenv'):
        run('./manage.py syncdb')
        run('./manage.py loaddata myfixture')

这将导致像这样的执行:

$ cd /path/to/app && workon myvenv && ./manage.py syncdb
$ cd /path/to/app && workon myvenv && ./manage.py loaddata myfixture

最后,如在开头附近提到的,prefix 可以根据需要嵌套。:

with prefix('workon myenv'):
    run('ls')
    with prefix('source /some/script'):
        run('touch a_file')

结果:

$ workon myenv && ls
$ workon myenv && source /some/script && touch a_file

设计,但希望说明。

fabric.context_managers.quiet()

别名到 settings(hide('everything'), warn_only=True)

用于包装您期望偶尔失败的远程疑问命令,和/或想要沉默的命令。

例:

with quiet():
    have_build_dir = run("test -e /tmp/build").succeeded

在任务中使用时,上述代码段不会产生任何 run: test -e /tmp/build 行,也不会忽略任何stdout/stderr显示和命令失败。

1.5 新版功能.

fabric.context_managers.remote_tunnel(*args, **kwds)

创建将本地可见端口转发到远程目标的隧道。

例如,您可以让远程主机访问客户端主机上安装的数据库:

# Map localhost:6379 on the server to localhost:6379 on the client,
# so that the remote 'redis-cli' program ends up speaking to the local
# redis-server.
with remote_tunnel(6379):
    run("redis-cli -i")

数据库可能安装在只能从客户端主机访问的客户端上(而不是客户端本身的 on):

# Map localhost:6379 on the server to redis.internal:6379 on the client
with remote_tunnel(6379, local_host="redis.internal")
    run("redis-cli -i")

remote_tunnel 最多接受四个参数:

  • remote_port (强制)是要监听的远程端口。

  • local_port (可选)是要连接的本地端口;默认端口与远程端口相同。

  • local_host (可选)是本地可连接的计算机(DNS名称或IP地址)连接;默认值为 localhost (即,运行同一计算机Fabric)。

  • remote_bind_address (可选)是当前目标上要绑定以进行侦听的远程IP地址。它应该是分配给目标上的接口的IP地址(或解析为此类IP的DNS名称)。可以使用“0.0.0.0”绑定所有接口。

注解

默认情况下,大多数SSH服务器只允许远程隧道侦听localhost接口(127.0.0.1)。在这些情况下,服务器忽略 remote_bind_address,隧道将仅侦听127.0.0.1。

fabric.context_managers.settings(*args, **kwargs)

嵌套上下文管理器和/或覆盖 env 变量。

settings 有两个目的:

  • 最有用的是,它允许用任何提供的关键字参数临时重写/更新 envwith settings(user='foo'):。一旦 with 块关闭,原始值(如果有)将被恢复。

    • 关键字参数 clean_revertsettings 本身有特殊的意义(见下文),在执行之前将被剥离。

  • 此外,它将使用 contextlib.nested 嵌套任何给定的非关键字参数,这应该是其他上下文管理器,例如。 with settings(hide('stderr'), show('stdout')):

如果需要,可以同时指定这些行为。一个例子将希望说明为什么这被认为是有用的:

def my_task():
    with settings(
        hide('warnings', 'running', 'stdout', 'stderr'),
        warn_only=True
    ):
        if run('ls /etc/lsb-release'):
            return 'Ubuntu'
        elif run('ls /etc/redhat-release'):
            return 'RedHat'

上述任务执行 run 语句,但如果 ls 失败,则警告而不是中止,并且防止所有输出(包括警告本身)向用户打印。在这种情况下,最终结果是一个完全无声的任务,允许调用者确定远程主机是什么类型的系统,而不会产生通常会发生的少量输出。

因此,settings 可以用于设置与隐藏(或示出)特定输出级别串联的环境变量的任何组合,或者与作为上下文管理器实现的任何其他Fabric结构功能串联。

如果 clean_revert 设置为 True,则 settings 恢复在嵌套块中更改的键,而不是仅恢复其值与给定值相同的键。更多的例子将使这一点清楚;下面是 settings 如何正常工作:

# Before the block, env.parallel defaults to False, host_string to None
with settings(parallel=True, host_string='myhost'):
    # env.parallel is True
    # env.host_string is 'myhost'
    env.host_string = 'otherhost'
    # env.host_string is now 'otherhost'
# Outside the block:
# * env.parallel is False again
# * env.host_string is None again

env.host_string 的内部修改被无效 - 不总是可取的。这是 clean_revert 进来的地方:

# Before the block, env.parallel defaults to False, host_string to None
with settings(parallel=True, host_string='myhost', clean_revert=True):
    # env.parallel is True
    # env.host_string is 'myhost'
    env.host_string = 'otherhost'
    # env.host_string is now 'otherhost'
# Outside the block:
# * env.parallel is False again
# * env.host_string remains 'otherhost'

如果 clean_revert 是活动的,在使用 settings 之前在 env 中不存在的全新密钥也被保留。当 False 时,当块退出时,这些键被删除。

1.4.1 新版功能: clean_revert kwarg。

fabric.context_managers.shell_env(**kw)

为包装的命令设置shell环境变量。

例如,下面显示了如何在安装Python ZMQ库时设置与ZeroMQ相关的环境变量:

with shell_env(ZMQ_DIR='/home/user/local'):
    run('pip install pyzmq')

prefix 一样,这有效地将 run 命令转换成:

$ export ZMQ_DIR='/home/user/local' && pip install pyzmq

可以同时给出多个键值对。

注解

如果用于影响从Windows本地主机运行时 local 的行为,将使用 SET 命令来实现此功能。

fabric.context_managers.show(*args, **kwds)

用于将给定输出 groups 设置为True的上下文管理器。

groups 必须是一个或多个字符串,用于命名在 output 中定义的输出组。在封闭块的持续时间内,给定组将设置为True,然后恢复为之前的值。

例如,要打开调试输出(默认情况下通常为关闭):

def my_task():
    with show('debug'):
        run('ls /var/www')

由于几乎所有输出组都默认显示,show 最有用的是打开常闭隐藏的 debug 组,或者当您知道或怀疑调用您自己的代码的代码试图用 hide 隐藏输出时。

fabric.context_managers.warn_only()

别名到 settings(warn_only=True)