1、Fabric API 以及实例讲解 Core API 核心API主要有七类:带颜色的输出类(color output),上下文管理类(context managers), 装饰器类(decorators), 网络类(network), 操作类(oprations), 任务类(tasks), 工具类(utils)。 Color Output 每一个包含这个模块的函数返回String带有颜色。比如: 1. From fabric.api import green,red 2. Print (red("This sentence is red, except for " + green
2、"these words, which are green") + ".")) 共包括以下: 1. fabric.colors.blue(text, bold=False) 2. fabric.colors.cyan(text, bold=False) 3. fabric.colors.green(text, bold=False) 4. fabric.colors.magenta(text, bold=False) 5. fabric.colors.red(text, bold=False) 6. fabric.colors.white(text, bold=False)
3、7. fabric.colors.yellow(text, bold=False) Context Managers Context Managers使用都需要结合with语句。连续使用多个时可嵌套也可用逗号隔开连接使用。 举例如下: 1. with cd('/path/to/app'): 2. with prefix('workon myvenv'): 3. run('./manage.py syncdb') 4. run('./manage.py loaddata myfixture') 它等价于 1. with cd('/path
4、/to/app'), prefix('workon myvenv'): 2. run('./manage.py syncdb') 3. run('./manage.py loaddata myfixture') 注意此时在python2.5中的写法:with nested(cd('/path/to/app'), prefix('workon myvenv')): 此类包括: 1. fabric.context_managers.cd(path) cd(远程主机更新工作目录) 任何被包括在 with cd(path):代码块里的命令run/sudo/get/put
5、相当于执行"cd && " 那么很明显它与 shell 命令cd的区别举例如下: 1. with cd('/var/www'): 2. run('ls') # Turns into "cd /var/www && ls" 比较 1. run('cd /var/www') 2. run('ls') 前者相当于执行:run(‘cd /var/www && ls’) 后者相当于执行:ls 时并没在/var/www 路径下,而是在默认路径$HOME路径下 cd 可嵌套: 1. with cd('/var/www'): 2. run('ls') # cd /var/
6、www && ls 3. with cd('website1'): 4. run('ls') # cd /var/www/website1 && ls fabric.contextmanagers.lcd(path) lcd(本地主机更新工作目录) 同 cd用法相同,只是它改变的的是本地工作目录,而 cd 改变的远程主机工作目录,所以它只能改变local的调用以及put/get的本地参数,它的默认路径与fabfile所在路径相关,由环境变量env.realfabfile指定 目前,cd和lcd的实现视是通过改变环境变量env.cwd和env.lcwd实现的,所以
7、如果要实现这个也可以通过环境变量来实现,但是不建议这么做。因为按照官方文档说明,将来这种实现方式可能要改。 fabric.context_managers.hide(*groups) hide(将指定参数输出级别默 认设置为 False) 指定默认隐藏的输出级别 group是一个或多个之前output 指定的类别之一,执行时它会将这些输出类型置为False。 比如你不想看到[hostname]:run:xxxx,以及阻止标准输出和错误就可以用下面这样 1. def my_task(): 2. with hide('running', 'stdout', 'stderr'): 3
8、 run('ls /var/www') 4. fabric.context_managers.show(\*groups) show(将指定参数输出级别默 认设置为 False) 指定默认输出的输出级别 用法同 hide,作用刚好相反。默认是所有都输出,所以show的一个作用就是打开默认隐藏的debug。 fabric.context_managers.path(path, behavior='append') 默认设置为将参数path附加在系统/用户环境变量$PATH,即 "PATH=$PATH: "指定 run/sudo 路径 behavior默认还有两个参数:
9、1. prepend:将指定参数path在$PATH前置即:PATH=
10、anage.py syncdb') 等价于执行#workon myvenv && ./manage.py syncdb 嵌套调用举例: 1. with prefix('workon myenv'): 2. run('ls') 3. with prefix('source /some/script'): 4. run('touch a_file') 结果是: 1. $ workon myenv && ls 2. $ workon myenv && source /some/script && touch a_file 和cd 是兼容的,结合使用
11、举例: 1. with cd('/path/to/app'): 2. with prefix('workon myvenv'): 3. run('./manage.py syncdb') 4. run('./manage.py loaddata myfixture') 结果如下: 1. $ cd /path/to/app && workon myvenv && ./manage.py syncdb 2. $ cd /path/to/app && workon myvenv && ./manage.py loaddata myfixture
12、 fabric.context_managers.settings(*args, **kwargs) setting(嵌套的上下文管理器覆盖env 变量) 它有两个作用: 大多数情况下,它会暂时覆盖/更新任何提到的关键字的 env 变量的值。比 如 : with settings(user='foo'): 相 当 于 设 定env.user=‘foo’。出了这个代码块,setting 中的值就会失效。此时注意 clean_revert=True 对作用域的影响,若此时在代码块中重新更新 env 的值,则该值就被更新即使出了代码块直到下 次 更 新 。 1. # Before the blo
13、ck, env.parallel defaults to False, host_string to None 2. with settings(parallel=True, host_string='myhost'): 3. # env.parallel is True 4. # env.host_string is 'myhost' 5. env.host_string = 'otherhost' 6. # env.host_string is now 'otherhost' 7. # Outside the block: 8. # * env
14、parallel is False again 9. # * env.host_string is None again 另 外 , 它 还 能 对 env 变 量 中 未 提 到 的 关 键 字(即env变量中没有的,这些可能会是其他的上下文管理器) 进 行 指 定 值 , 比 如 : 1. def my_task(): 2. with settings( 3. hide('warnings', 'running', 'stdout', 'stderr'), 4. warn_only=True 5. ): 6.
15、 if run('ls /etc/lsb-release'): 7. return 'Ubuntu' 8. elif run('ls /etc/redhat-release'): 9. return 'RedHat' 最后就是clean_revert设置带来的变化注意对比前面例子: 1. # Before the block, env.parallel defaults to False, host_string to None 2. with settings(parallel=True, host_string='
16、myhost', clean_revert=True): 3. # env.parallel is True 4. # env.host_string is 'myhost' 5. env.host_string = 'otherhost' 6. # env.host_string is now 'otherhost' 7. # Outside the block: 8. # * env.parallel is False again 9. # * env.host_string remains 'otherhost' Decorators 1
17、 fabric.decorators.hosts(\*host_list) 定义哪个或者哪些主机来执行这些命令,定义方式: 2. @hosts('host1') 3. @hosts('host1', 'host2') 4. @hosts(['host1','host2'])) 5. fabric.decorators.roles(\*role_list) 定义执行任务的 roles,与主机对应 6. env.roledefs.update({ 7. 'webserver': ['www1', 'www2'], 8. 'dbserver': ['db1']}
18、) 9. @roles('webserver', 'dbserver') 10. def my_func(): 11. pass 同hosts一样,roles的参数既可以是一个参数列表,或者一个可迭代对象 1. fabric.decorators.serial(func) (串行执行,不允许并行)强制func串行执行 2. fabric.decorators.parallel(pool_size=None) (并行执行,而不是串行) 3. fabric.decorators.task(\*args, **kwargs) 即新风格任务,参照前面定义任务时的参数给其设定
19、参数 4. fabric.decorators.with_settings(\*arg_settings, **kw_settings) 作用同于上下文管理器中的with,只是它的作用域应该是整个函数。 5. @with_settings(warn_only=True) 6. def foo(): 7. ... 8. fabric.decorators.runs_once(func) 函数仅执行一次 Network 1. work.disconnect_all() 用于与所有当前连接的服务器断开连接。一般用于 fab 主循环,也同时用于将Fabric作为类库使用。
20、Operations 1. fabric.operations.get(remote_path, local_path=None)从 远 程 主 机下载一个或多个文件 2. fabric.operations.put(local_path, remote_path, use_sudo=False, mirror_local_mode=False, mode=None) 从本地上传一个或多个文件至远程主机 很多时候用法类似scp或cp,用于上传下载文件,它的本地和远程路径实现发别是通过lcd和cd实现,所以用上下文管理器的cd会影响远程路径参数,而lcd会影响本地路径参数。这里主要是弄明白
21、本地路径和远程路径的表示,它们将路径分成host/dirname/basename/path,可分别用基于字典的方式来指定,这里具体可查文档说明。 1. fabric.operations.open_shell(command=None) 在远程主机调用交互式shell。 如果命令给定,它将会在调用用户之前被送至管道。当你需要一个完全基于shell调用和一系列命令 时非常有用,比如debug的时候。这可以被看作是run的简单版,但并不是可替代版,因为它无法 处理远程交互中遇到的prompt,标准输入,login等问题。此外,它没有返回值而且在发生错误时也 不会有fabric的错误处理
22、机制。 1. fabric.operations.reboot(wait=120) 重启远程机器,会暂时调整fabric冲连接设置以保证在wait时间内重连接成功。 1. fabric.operations.run(command, shell=True, pty=True, combine_stderr=True)在远程主机执行shell命令。 如果shell为True,run会将给定的命令通过env.shell设定的shell上解释。命令参数中任何双引号“和$符都会被忽略。 run会将远程程序的标准输出作为一个单一(可能多行)string作为结果返回。这个string包括布尔值
23、的failed和succeed的属性来标志命令执行的成功与失败, 以及一个结果码来做为返回的 return_code属性。 本地终端的任何文本的输入在run执行过程中都会被送往远程程序,来允许你更自然地处理密码和其他prompts。 你可以使用pty=False来放弃在远程主机上创建伪终端以防其在命令存在问题时会制造麻烦。然而,这会强制fabric自己在run运行时echo所有的输入和你的键入,包括大小写敏感的密码。远程伪终端会替你echo,而且会只能的处理密码这种prompts。 同样地,如果你需要编程检测远程程序的标准错误流(利用函数返回值的stderr属性),你可以设置combi
24、nestderr=False。这样做会使你终端输出很混乱(虽然返回strings能合理地分开)。但是这是你单独获取标准错误流的唯一方式。设置pty=combinestderr=False。 1. fabric.operations.sudo(command, shell=True, pty=True, combine_stderr=True, user=None) 以上连个命令都是在远程执行命令,后者拥有特殊权限,关于参数含义已经在远程交互中详细介绍和run中介绍。 它们的返回结果是一个多行 string,这个 string 会有 failed, succeeded,return_cod
25、e 这样的属性来标识是否执行成功。 同样地,如果你需要编程检测远程程序的标准错误流(利用函数返回值的stderr属性),你可以设置combine_stderr=False。这样做会使你终端输出很混乱(虽然返回strings能合理地分开)。 sudo会多接受一个user的参数,这用来允许你在其他用户而不是root用户来执行命令。在很多系统,user可以是string的username或者是int的uid。 此外上述各函数都有相应的参数为(args, *kwargs)的重载函数。 1. fabric.operations.local(command, capture=False) 使用
26、python subprocess 模块实现且 shell=True,local 现在能够打印和捕捉输出,正如 run/sudo 一样。caputure 参数允许你选择是打印还是捕捉输出。 1. caputure=False 时,本地 subprocess 的标准输出和错误直接显示在终端,可通过全局输出控制,output.stdout 等,此时返回为空。 2. caputure=True 时,命令 stdout 作为类 string 对象返回,同 run/sudo 一样,返回值有 return_code,stderr,failed 和 succeeded 属性。 Tasks class
27、 fabric.tasks.Task(alias=None, aliases=None, default=False, args, *kwargs) 对于抽象基类和子类处理不同 详细参数含义可参考定义任务中新风格任务的参数含义。 fabric.tasks.execute(task, args, *kwargs) 执行任务无论是新风格的任务名还是经典风格的可调用对象。 任务会在该任务主机列表中每个主机上执行一遍,这些主机列表包括来自命令行-H,装饰器@hosts,@roles,env.hosts等等。 host/hosts/role/roles、exclude_hosts都可以作为参数传递
28、进去来设置该任务的主机列表。 如果task还有其他参数需要传递,比如 1. execute(mytask, 'arg1', kwarg1='value')将会执行 2. mytask('arg1', kwarg1='value') 它的执行结果也是按字典形式返回,比如execute(foo,hosts=['a', 'b']) 结果可能是{'a': None, 'b': 'bar'} 如果设置了skipbadhosts则该主机返回值可能为错误对象或消息。 Utils 1. fabric.utils.abort(msg)放弃执行,打印msg为stderr和错误状态。 2. fab
29、ric.utils.error(message, func=None, exception=None, stdout=None, stderr=None)调用func,给出指定错误、输出等信息。 3. fabric.utils.fastprint(text, show_prefix=False, end='', flush=True) 4. fabric.utils.indent(text, spaces=4, strip=False)同puts相同,只是不同的参数,快速打印文本text,不用等行结尾。 5. fabric.utils.puts(text, show_prefix=Non
30、e, end='\n', flush=False)
6. fabric.utils.warn(msg)打印警告信息,但是不放弃执行。
Contrib API
一般使用较少,所以简单介绍
console output 工具
1. confirm(询问用户问题,返回 Y/N,比如“是否继续”这样的问题)
django 集成
1. project:设置 DJANGO_SETTINGS_MODULE to '
31、的事,目前不成熟。 文件和目录管理 1. append(附加,类似 java 中 FileWriter 的 append 方法) 2. contains(返回文件是否存在该文本) 3. exits(返回远程主机是否存在该路径) 4. first(返回多个文件中第一个找到的) 5. upload_template(上传远程主机模板) 项目工具 1. rsync_project(使用 rsync 同步远程目录与当前项目目录) Fabric核心API: Color output functions 颜色打印: #打印颜色输出,绿色输出 from
32、fabric.colors import green print(green("This text is green!")) #红色和绿色输出 from fabric.colors import red, green print(red("This sentence is red, except for " + green("these words, which are green") + ".")) #其他的一些颜色api #其中第二个参数bold用于显示输出的信息是加粗显示 fabric.colors.blue(text, bold=False) fabric.
33、colors.cyan(text, bold=False) fabric.colors.green(text, bold=False) fabric.colors.magenta(text, bold=False) fabric.colors.red(text, bold=False) fabric.colors.white(text, bold=False) fabric.colors.yellow(text, bold=False) Context managers for use with the with statement. #使用with声明进
34、行上下文管理 which doesn’t work due to how shell-less SSH connections are implemented – state is not kept between invocations of run or sudo: fabric.context_managers.cd(path) 用于切换在远程主机的目录,如果要和其他命令组合使用的话需要使用with声明,默认cd切换远程目录是对其他命令不影响的。 例如,我想切换到/var/www目录下显示目录下的内容: cd("/var/www") run("ls") 上面的这段代码
35、的结果是不正确的 正确的做法是需要结合with声明 with cd("/var/www"): run("ls") 如果想在本地目录切换的话就使用lcd fabric.context_managers.char_buffered(pipe) 强制本地终端的管道类型是character而不是line和buffered,仅用于是unix终端下,在windows下无需设置 fabric.context_managers.hide(*groups) 隐藏指定的输出: groups中包括: Status 状态信息,通常用户使用键盘终端,或者是serv
36、er断开了连接,这些status信息很重要 aborts 中止信息,类似状态信息,仅仅到fabric当作是library的时候需要关闭,即使这个被关闭了,aborts仍然发生 warnings 警告信息, running 运行过程中的一些输出,比如命令正在运行过程中或者file传输过程中的一些输出 stdout 标准输出 本地或者远程与命令相关的标准输出 stderr 标准错误输出 本地或者远程与命令相关的错误输出 user 用于生产的一些信息(比如本地打印的一些信息) 例子: def test_hide():
37、with hide('stdout','stderr'): run("ls -al") 上面的例子将不会有任何输出,因为标准输出和标准输入都隐藏了 fabric.context_managers.lcd(path) 实现对本地目录的切换 例子: def test_lcd(): with lcd("/var/www"): local("scp ./* 172.16.35.2:~/") 上面的列子将会把/var/www中的文件拷贝到172.16.35.2的家目录中 fabric.context_managers.p
38、ath(path, behavior='append') 设置PATH环境变量,用于直接执行shell命令,不需要使用绝对路径。 有三种behavior: append 对PATH变量进行追加(追加到其后) prepend 对PATH变量进行追加(追加到其前) replace 对PATH变量之间进行替换 例子: def test_path(): with path("/usr/local/nginx/sbin/",behavior='append'): run("nginx") 上面的例子将会启动远程主机的nginx,在
39、此之前你要先定义好env.hosts和env.password,还要就是别忘了导入path fabric.context_managers.prefix(command) 对任何包裹在sudo和run里面的命令加上&& with prefix('cd /tmp'): run('./manage.py syncdb') 上面的代码等同于cd /tmp && ./manage.py syncdb prefix的嵌套使用: with prefix('cd /var/www'): run('ls')
40、 with prefix('cd html'): run('ls') 上面的代码等同于: cd /var/www && ls cd /var/www && cd html && ls fabric.context_managers.quiet() 是settings(hide('everything'), warn_only=True)的别名,用于隐藏一些输出,并且warn_only用于设置当发生错误的时候不是直接 Aborting直接终止程序而是出现warning警告并正常退出. fa
41、bric.context_managers.remote_tunnel(*args, **kwds) 用于建立一个通道,转发本地的一个可见端口到远程 例子: def test_remote(): with remote_tunnel(80): run("curl http://127.0.0.1") 上面的例子代表:在远程执行curl http://127.0.0.1访问远程主机的本地80端口,而这个80端口是映射到本地主机的80端口 所以最终的结果就是在远程主机上访问本地主机的80端口 fabric.context_managers.set
42、tings(*args, **kwargs) 用于设置一些fabric内置变量,这个之前使用了,这里就不举列子了 fabric.context_managers.shell_env(**kw) 用于设置shell环境变量,相当于使用export命令导出环境变量 例子 def test_shell(): with shell_env(TEST="test"): run("echo $TEST") 上面的例子将会在远程主机设置一个TEST的变量,然后输出 fabric.context_managers.show(*args, **kwds) 和hide相反,用于开启一些输出的 fabric.context_managers.warn_only() 前面已经谈论到这个变量的作用,这里就不再说了






