關(guān)于fabric
fabric是一款python庫(kù)来累,可以在執(zhí)行本地或者遠(yuǎn)端服務(wù)器上執(zhí)行shell命令瘤运,一般用于遠(yuǎn)程部署應(yīng)用或者運(yùn)維工作钱磅。
你要注意的事
由于fabric的作者更新了代碼味赃,python2.x和python3.x使用方式有所不同狠持,所以在使用之前昭齐,請(qǐng)睜開(kāi)眼睛看看你的環(huán)境中的fabric是哪個(gè)版本喧枷,$ pip show fabric帽借。
我當(dāng)時(shí)安裝的時(shí)候是默認(rèn)版本,2.4退子。
如果你的1.x版本福扬,就不要往下看了汽烦。這有1.x的基礎(chǔ)教程:傳送門颈将。
安裝
怎么快怎么來(lái)噪奄,一條命令即可:pip install fabric戳护。
如果你的項(xiàng)目是在虛擬環(huán)境中,不要忘了開(kāi)啟虛擬環(huán)境再安裝哦。
使用
fabric默認(rèn)的任務(wù)路徑是fabfile/init.py爬迟,也可以是fabfile.py菊匿。
比如說(shuō)付呕,我建了個(gè)項(xiàng)目叫"nzh_project",我想在這里執(zhí)行fabric任務(wù)跌捆,那么你就把fabfile.py文件建在這里徽职。
打開(kāi)fabfile.py,并輸入如下代碼:
from invoke import task
@task
def hello(c):
print("Hello Fabric")
然后在pycharm編譯器中的terminal中輸入fab hello佩厚,就能看到輸出結(jié)果姆钉。
如果報(bào)錯(cuò)了
那么你看看是不是以下問(wèn)題:
1.路徑錯(cuò)誤,你必須切換到fabfile.py所在的路徑。
2.pycharm解釋器不對(duì)潮瓶,有的同學(xué)可能和我一樣用的是虛擬環(huán)境陶冷,虛擬環(huán)境是獨(dú)立的,不會(huì)受到系統(tǒng)環(huán)境的影響毯辅,所以如果沒(méi)有切換pycharm的python解釋器也會(huì)報(bào)錯(cuò)埂伦,在你import fabric的時(shí)候就會(huì)報(bào)錯(cuò)。
再?gòu)U話一句思恐,怎么切換python解釋器
在1處搜索“interpreter”沾谜,選中project interpreter,在下拉框中查看是否有你的虛擬環(huán)境解釋器壁袄,如果沒(méi)有的話类早,點(diǎn)擊4處的齒輪,選擇add local嗜逻。
在Exist environment中選擇你的虛擬環(huán)境中/bin/python3.6涩僻。我是3.6,你用的什么就選什么栈顷。
回來(lái)繼續(xù)說(shuō)正題
fabric 2.x需要使用task裝飾器來(lái)標(biāo)識(shí)函數(shù)逆日,這個(gè)被標(biāo)識(shí)的函數(shù)被稱為fabric任務(wù)。
這個(gè)任務(wù)要被執(zhí)行萄凤,必須標(biāo)注@task室抽。
再說(shuō)一下為什么hello函數(shù)要傳個(gè)參數(shù)c,如果不傳就會(huì)報(bào)TypeError錯(cuò)誤靡努。
說(shuō)是缺少一個(gè)初始化上下文參數(shù)坪圾,隨便傳一個(gè)即可。
如何調(diào)用task
任務(wù)(@task標(biāo)識(shí)的函數(shù))我們寫(xiě)完了惑朦,那么接下來(lái)就要知道如何調(diào)用兽泄。
回到終端,輸入 fab --list漾月,查看task列表.
我們可以看到病梢,里面有個(gè)可用任務(wù)hello,不正是我們寫(xiě)的hello函數(shù)么梁肿。
繼續(xù)在終端中輸入蜓陌,fab hello,完成調(diào)用吩蔑。
在遠(yuǎn)程服務(wù)器執(zhí)行shell命令
fabric的強(qiáng)大在于你可以通過(guò)SSH在遠(yuǎn)程服務(wù)器執(zhí)行shell命令钮热。
那么,我們可以寫(xiě)一個(gè)簡(jiǎn)單的“查看當(dāng)前路徑所有文件的命令”烛芬,這個(gè)命令是在遠(yuǎn)程服務(wù)器上執(zhí)行的隧期。
from invoke import task
from fabric import Connection
@task
def hello(c):
# c.run("echo ‘hello fabric‘")
print("Hello Fabric")
@task
def show_files(r):
c = Connection('xx.xx.xx.xx', user='root', port=22, connect_kwargs={'password': '密碼'})
c.run('ls')
show_files(r)里的參數(shù)r是隨便寫(xiě)的痴奏,因?yàn)槲乙膊恢浪歉缮兜摹?br>
要連接遠(yuǎn)程服務(wù)器必須有IP地址(或者域名),賬號(hào)厌秒,密碼,端口號(hào)擅憔。
所以我們要先從fabric導(dǎo)入Connection類鸵闪,初始化時(shí)傳入這些參數(shù)。
c就是一個(gè)連接實(shí)例暑诸,可以理解為sqlalchemy中操作數(shù)據(jù)庫(kù)的游標(biāo)cursor蚌讼。
你對(duì)遠(yuǎn)程服務(wù)器操作都寫(xiě)在run函數(shù)中。
比如我想在服務(wù)器上執(zhí)行l(wèi)s命令个榕,那么把ls傳入到run函數(shù)中即可篡石。
注意
再次查看可執(zhí)行任務(wù)時(shí),發(fā)現(xiàn)show_files函數(shù)名字變了西采,變成了show-files凰萨。
如果不注意,你在終端輸入fab show_files時(shí)會(huì)發(fā)現(xiàn)械馆,提示“No idea what 'show_files' is!”胖眷,也許是命名規(guī)則的問(wèn)題吧,所以注意規(guī)避就好了霹崎。
執(zhí)行的時(shí)候要輸入fab show-files珊搀。
那應(yīng)用程序分布在多臺(tái)服務(wù)器上時(shí)
很有可能遇到這樣的情況,你的應(yīng)用托管到多臺(tái)服務(wù)器上尾菇,我們總不能每臺(tái)服務(wù)器都寫(xiě)個(gè)腳本吧境析?這種情況有兩種解決辦法。
1.如果這些服務(wù)器的賬號(hào)密碼都一樣派诬,給hostname傳入一個(gè)ip地址的list劳淆。(這種方法沒(méi)試過(guò)。)
2.如果每臺(tái)服務(wù)器賬號(hào)密碼不一樣千埃,那就對(duì)每臺(tái)服務(wù)器都建立一個(gè)Connection憔儿。
c1 = Connection('xx.xx.xx.xx', user='xxx', port=22, connect_kwargs={'password': 'xxxx'})
c2 = Connection('xx.xx.xx.xx', user='xxx', port=22, connect_kwargs={'password': 'xxxx'})
c3 = Connection('xx.xx.xx.xx', user='xxx', port=22, connect_kwargs={'password': 'xxxx'})
for i in [c1, c2, c3]:
i.run('ls')