ShutIt:一個基於 Python 的 shell 自動化框架
(點擊
上方藍字
,快速關注我們)
編譯:雁驚寒 英文:ShutIt
www.iteye.com/news/32482
如有好文章投稿,請點擊 → 這裡了解詳情
譯者註:本文通過實例簡單介紹了ShutIt這個基於Python的自動化框架的使用方法。除了pexpect,我們又多了這個選擇。以下是譯文。
ShutIt是一個易於使用的基於shell的自動化框架。它對基於python的expect庫(pexpect)進行了包裝。你可以把它看作是「沒有痛點的expect」。它可以通過pip進行安裝。
Hello World
讓我們從最簡單的例子開始吧。創建一個名為example.py的文件:
import
shutit
session
=
shutit
.
create_session
(
"bash"
)
session
.
send
(
"echo Hello World"
,
echo
=
True
)
運行這個文件:
python example.py
輸出:
python
example
.
py
echo
"Hello World"
echo
"Hello World"
Hello World
Ians
-
MacBook
-
Air
.
local
:
ORIGIN_ENV
:
RhuebR2T
#
「send」函數的第一個參數是要運行的命令。「echo」的參數將會輸出到終端上。默認情況下,ShutIt是靜默的。
登錄伺服器
如果你要登陸一台伺服器並執行伺服器上的命令。可以將example.py改為:
import
shutit
session
=
shutit
.
create_session
(
"bash"
)
session
.
login
(
"ssh you@example.com"
,
user
=
"you"
,
password
=
"mypassword"
)
session
.
send
(
"hostname"
,
echo
=
True
)
session
.
logout
()
程序將登錄到這台伺服器上,並輸出主機名。
hostname
hostname
example
.
com
example
.
com
:
cgoIsdVv
:
heDa77HB
#
顯然,這很不安全!你可以這樣運行:
import
shutit
session
=
shutit
.
create_session
(
"bash"
)
password
=
session
.
get_input
(
""
,
ispass
=
True
)
session
.
login
(
"ssh you@example.com"
,
user
=
"you"
,
password
=
password
)
session
.
send
(
"hostname"
,
echo
=
True
)
session
.
logout
()
它會讓你輸入密碼:
Input
Secret
:
hostname
hostname
example
.
com
example
.
com
:
cgoIsdVv
:
heDa77HB
#
同樣的,「login」方法在登錄後改變了提示符。你給了ShutIt一個登錄命令,並附帶用戶名和密碼(如果需要的話),然後,ShutIt會完成剩餘的事情。
「logout」負責終止「login」,並向屏幕輸出發生的任何變化。
登錄到多台伺服器
假設你有一個集群包含兩台伺服器,並希望同時登錄到這兩個伺服器上去。則只需要創建兩個會話,並運行類似的login和send命令:
import
shutit
session1
=
shutit
.
create_session
(
"bash"
)
session2
=
shutit
.
create_session
(
"bash"
)
password1
=
session1
.
get_input
(
"Password for server1"
,
ispass
=
True
)
password2
=
session2
.
get_input
(
"Password for server2"
,
ispass
=
True
)
session1
.
login
(
"ssh you@one.example.com"
,
user
=
"you"
,
password
=
password1
)
session2
.
login
(
"ssh you@two.example.com"
,
user
=
"you"
,
password
=
password2
)
session1
.
send
(
"hostname"
,
echo
=
True
)
session2
.
send
(
"hostname"
,
echo
=
True
)
session1
.
logout
()
session2
.
logout
()
將輸出這樣的結果:
$
python
example
.
py
Password
for
server1
Input
Secret
:
Password
for
server2
Input
Secret
:
hostname
hostname
one
.
example
.
com
one
.
example
.
com
:
Fnh2pyFj
:
qkrsmUNs
# hostname
hostname
two
.
example
.
com
two
.
example
.
com
:
Gl2lldEo
:
D3FavQjA
#
實例:監控多台伺服器
我們可以通過添加一些代碼邏輯來檢查命令的輸出,從而將上述代碼變成一個簡單的監控工具:
import
shutit
capacity_command
=
"""df / | awk "{print $5}" | tail -1 | sed s/[^0-9]//"""
session1
=
shutit
.
create_session
(
"bash"
)
session2
=
shutit
.
create_session
(
"bash"
)
password1
=
session
.
get_input
(
"Password for server1"
,
ispass
=
True
)
password2
=
session
.
get_input
(
"Password for server2"
,
ispass
=
True
)
session1
.
login
(
"ssh you@one.example.com"
,
user
=
"you"
,
password
=
password1
)
session2
.
login
(
"ssh you@two.example.com"
,
user
=
"you"
,
password
=
password2
)
capacity
=
session1
.
send_and_get_output
(
capacity_command
)
if
int
(
capacity
)
<
10
:
(
"RUNNING OUT OF SPACE ON server1!"
)
capacity
=
session2
.
send_and_get_output
(
capacity_command
)
if
int
(
capacity
)
<
10
:
(
"RUNNING OUT OF SPACE ON server2!"
)
session1
.
logout
()
session2
.
logout
()
在這裡,我們用了「sendandget_output」方法來獲取capacity_command命令的輸出。
還有很多更加優雅的方法可以完成上面的操作,但這取決於你想要Python有多聰明。
更複雜的IO – Expecting
假設你需要跟一個命令行程序進行交互,並且要實現自動化操作。在這裡,我們使用telnet來舉一個簡單的例子:
import
shutit
session
=
shutit
.
create_session
(
"bash"
)
session
.
send
(
"telnet"
,
expect
=
"elnet>"
,
echo
=
True
)
session
.
send
(
"open google.com 80"
,
expect
=
"scape character"
,
echo
=
True
)
session
.
send
(
"GET /"
,
echo
=
True
,
check_exit
=
False
)
session
.
logout
()
注意「expect」的參數。你只需要給出telnet提示符的一個子集來進行匹配。
注意「check_exit」的參數,後面我們會講到這個參數的。上面這段代碼將輸出:
$
python
example
.
py
telnet
telnet
>
open
.
com
80
Trying
216.58.214.14...
Connected to
.
com
.
Escape character
is
"^]"
.
GET
/
HTTP
/
1.0
302
Found
Cache
-
Control
:
private
Content
-
Type
:
text
/
html
;
charset
=
UTF
-
8
Referrer
-
Policy
:
no
-
referrer
Location
:
http
://
www
.
.
co
.
uk
/
?
gfe_rd
=
cr
&
ei
=
huczWcj3GfTW8gfq0paQDA
Content
-
Length
:
261
Date
:
Sun
,
04
Jun
2017
10
:
57
:
10
GMT
<
HTML
><
HEAD
><
meta
http
-
equiv
=
"content-type"
content
=
"text/html;charset=utf-8"
>
<
TITLE
>
302
Moved
TITLE
>
HEAD
><
BODY
>
<
H1
>
302
Moved
H1
>
The document has
moved
<
A
HREF
=
"http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA"
>
here
A
>
.
BODY
>
HTML
>
Connection closed by foreign
host
.
現在回到「checkexit = false」上來。由於telnet命令會返回一個錯誤的退出碼(1),我們不想讓腳本執行失敗,這裡的「checkexit = false」能讓ShutIt知道你並不關注這個退出碼。
如果你沒有傳入這個參數,ShutIt會給你一個互動式的提示,如果你有終端接入的話。這被稱為「暫停點」。
暫停點
你可以隨便在什麼時候通過調用以下方法來設置一個「暫停點」。
[...]
session
.
pause_point
(
"This is a pause point"
)
[...]
當腳本運行到暫停點時,同時按下「Ctrl」和「]」,則可以讓腳本繼續執行。這對於調試非常有用:添加一個暫停點,看看周圍,然後繼續。試試這個:
import
shutit
session
=
shutit
.
create_session
(
"bash"
)
session
.
pause_point
(
"Have a look around!"
)
session
.
send
(
"echo "Did you enjoy your pause point?""
,
echo
=
True
)
程序輸出:
$
python
example
.
py
Have
a
look
around
!
Ians
-
Air
.
home
:
ORIGIN_ENV
:
I00LA1Mq
# bash
imiell
@
Ians
-
Air
:/
space
/
git
/
shutit
?
master
+
?
CTRL
-
]
caught
,
continuing
with
run
...
2017
-
06
-
05
15
:
12
:
33
,
577
INFO
:
Sending
:
exit
2017
-
06
-
05
15
:
12
:
33
,
633
INFO
:
Output
(
squashed
)
:
exitexitIans
-
Air
.
home
:
ORIGIN_ENV
:
I00LA1Mq
# [...]
echo
"Did you enjoy your pause point?"
echo
"Did you enjoy your pause point?"
Did you enjoy your pause
point
?
Ians
-
Air
.
home
:
ORIGIN_ENV
:
I00LA1Mq
#
更複雜的IO – Backgrounding
回到我們上面的「監控多台伺服器」的例子上來。想像一下,我們要在每台伺服器上運行一個長時間運行的任務。默認情況下,ShutIt會持續運行很長時間。但是我們可以在後台運行任務來加快ShutIt的運行速度。
在這裡,你可以使用簡單的命令「sleep 60」來嘗試一個例子。
import
shutit
import
time
long_command
=
"""sleep 60"""
session1
=
shutit
.
create_session
(
"bash"
)
session2
=
shutit
.
create_session
(
"bash"
)
password1
=
session1
.
get_input
(
"Password for server1"
,
ispass
=
True
)
password2
=
session2
.
get_input
(
"Password for server2"
,
ispass
=
True
)
session1
.
login
(
"ssh you@one.example.com"
,
user
=
"you"
,
password
=
password1
)
session2
.
login
(
"ssh you@two.example.com"
,
user
=
"you"
,
password
=
password2
)
start
=
time
.
time
()
session1
.
send
(
long_command
,
background
=
True
)
session2
.
send
(
long_command
,
background
=
True
)
(
"That took: "
+
str
(
time
.
time
()
-
start
)
+
" seconds to fire"
)
session1
.
wait
()
session2
.
wait
()
(
"That took: "
+
str
(
time
.
time
()
-
start
)
+
" seconds to complete"
)
我的筆記本電腦說,運行這兩個命令只需花費0.5秒,而腳本在一分鐘以後才運行結束(使用了』wait』方法)。
雖然這個例子看起來是微不足道的,但是想像一下,如果你有數百台這樣的伺服器需要管理,那麼你可以看到這幾行代碼和一個python import所帶來的強大的力量。
更多信息
ShutIt可以做很多事。更多信息,請參閱:
ShutIt (https://ianmiell.github.io/shutit/)
GitHub (https://github.com/ianmiell/shutit/blob/master/README.md)
看完本文有收穫?請轉
發分享給更多人
關注「P
ython開發者」,提升Python技能


※2017,最受歡迎的 15大Python 庫有哪些?
※代碼這樣寫更優雅(Python 版)
※向正在運行的Python進程注入代碼
※Python——正則表達式基礎知識的簡介
※關於 Python 多線程的一些思考
TAG:Python |