fabric上下文管理

Fabric的上下文管理器是一系列与Python的with语句配合使用的方法,它可以在with语句块内设置当前工作环境的上下文。让我们介绍几个常用的情况:


cd: 设置远程机器的当前工作目录

cd()方法在之前的范例中出现过,with cd()语句块可以用来设置远程机的工作目录:

from fabric.api import env, cd, put
 
env.hosts = ['hellodemos', ]
env.password = '111111'
 
def hello():
	with cd('/var/www/'):
		put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz')

上例中的文件会上传到远程机的/var/www/目录下。出了with cd()语句块后,工作目录就回到初始的状态,也就是bjhee用户的根目录。

注意,如果你要运行这段代码,请将上面的代码保存为 python 文件,并将上面的目录更改为你的电脑上实际存在的目录。


lcd: 设置本地工作目录

lcd()就是local cd的意思,用法同cd()一样,区别是它设置的是本地的工作目录:

from fabric.api import env, cd, lcd, put
 
env.hosts = ['hellodemos', ]
env.password = '111111'
 
def hello():
	with cd('/var/www/'):
		with lcd('/tmp/'):
			put('myapp-0301.tar.gz', 'myapp.tar.gz')

这个例子的执行效果跟上个例子一样,这里有两个 with ,也就是有2个上下文,第一个cd是表示远程服务器定位到 /var/www 目录,第二个lcd表示本地目录定位到 /tmp/ 目录。当超出2个 with 之后,无论是服务器还是本地目录都恢复默认的目录中。


path: 添加远程机的PATH环境变量

from fabric.api import env, run, path
 
env.hosts = ['hellodemos', ]
env.password = '111111'
 
def hello():
	with path('/home/bjhee/tmp'):
		run('echo $PATH')
	run('echo $PATH')

假设我们的PATH环境变量默认是 /sbin:/bin,在上述 with path() 语句块内PATH变量将变为 /sbin:/bin:/home/bjhee/tmp。出了with语句块后,PATH又回到原来的值。

注意,path是临时添加环境变量的意思。例如远程主机上有2个python,需要临时使用某一个的时候,就可以通过环境变量解决。


settings: 设置Fabric环境变量参数

Fabric环境变量即是我们例子中一直出现的fabric.api.env,它支持的参数可以从官方文档中查到。

from fabric.api import env, run, settings

env.hosts = ['hellodemos', ]
env.password = '111111'

def hello():
	with settings(warn_only=True):
		run('echo $USER')

我们将环境参数warn_only暂时设为True,这样遇到错误时任务不会退出。


shell_env: 设置Shell环境变量

可以用来临时设置远程和本地机上Shell的环境变量。

from fabric.api import env, run, local, shell_env
 
env.hosts = ['hellodemos', ]
env.password = '111111'
 
def hello():
	with shell_env(JAVA_HOME='/opt/java'):
		run('echo $JAVA_HOME')
		local('echo $JAVA_HOME')

例子,只需要在这段脚本中引入java,就可以像这样做。


prefix: 设置命令执行前缀

from fabric.api import env, run, local, prefix
 
env.hosts = ['hellodemos', ]
env.password = '111111'
 
def hello():
	with prefix('echo Hi'):
		run('pwd')
		local('pwd')

在上述with prefix()语句块内,所有的run()local()方法的执行都会加上`echo Hi && “前缀,也就是效果等同于:

run('echo Hi && pwd')
local('echo Hi && pwd')

配合后一节我们会讲到的错误处理,它可以确保在prefix()方法上的命令执行成功后才会执行语句块内的命令。