Python Plumbum 簡介:用 Python 來寫指令碼

Tomer Filiba發表於2018-03-22

Python Plumbum 簡介:用 Python 來寫指令碼

Plumbum:Shell 組合器

你是否曾希望將 shell 指令碼緊湊地融入到真正的程式語言裡面? 那麼可以瞭解下 Plumbum Shell 組合器。Plumbum (lead 的拉丁語,以前用來製作管道)是一個小型但功能豐富的類庫,用於以 Python 進行類似 shell 指令碼程式設計。該庫的理念是 “永遠不要再寫 shell 指令碼”,因此它試圖合理地模仿 shell 語法(shell 組合器),同時保持 Python 特性和跨平臺

除了類似 shell 的語法便捷的快捷方式之外,該庫還提供本地和遠端命令執行(透過 SSH)、本地和遠端檔案系統路徑、簡單的工作目錄和環境操作、快捷訪問 ANSI 顏色,以及程式設計命令列介面(CLI)應用程式工具包。現在讓我們看一些程式碼!

其最新版本 1.6.6 釋出於 2018 年 2 月 12 日。

快捷使用指南

基本使用

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns

不需要為每個你想使用的命令寫 xxx = local["xxx"],你可以匯入命令列

>>> from plumbum.cmd import grep, wc, cat, head
>>> grep
LocalCommand(<LocalPath /bin/grep>)

參見本地命令列

管道

>>> chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"]
>>> print chain
/bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l
>>> chain()
u'13\n'

參見管道

重定向

>>> ((cat < "setup.py") | head["-n", 4])()
u'#!/usr/bin/env python\nimport os\n\ntry:\n'
>>> (ls["-a"] > "file.list")()
u''
>>> (cat["file.list"] | wc["-l"])()
u'17\n'

參見輸入/輸出重定向

工作目錄操作

>>> local.cwd
<Workdir /home/tomer/workspace/plumbum>
>>> with local.cwd(local.cwd / "docs"):
...     chain()
...
u'15\n'

參見路徑本地物件

前臺後和後臺執行

>>> from plumbum import FG, BG
>>> (ls["-a"] | grep["\\.py"]) & FG         # The output is printed to stdout directly
build.py
.pydevproject
setup.py
>>> (ls["-a"] | grep["\\.py"]) & BG         # The process runs "in the background"
<Future ['/bin/grep', '\\.py'] (running)>

參見前臺和後臺

命令列巢狀

>>> from plumbum.cmd import sudo
>>> print sudo[ifconfig["-a"]]
/usr/bin/sudo /sbin/ifconfig -a
>>> (sudo[ifconfig["-a"]] | grep["-i", "loop"]) & FG
lo        Link encap:Local Loopback
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

參見命令列巢狀

遠端命令(透過 SSH)

>>> from plumbum import SshMachine
>>> remote = SshMachine("somehost", user = "john", keyfile = "/path/to/idrsa")
>>> r_ls = remote["ls"]
>>> with remote.cwd("/lib"):
...     (r_ls | grep["0.so.0"])()
...
u'libusb-1.0.so.0\nlibusb-1.0.so.0.0.0\n'

參見遠端

CLI 應用程式

import logging
from plumbum import cli

class MyCompiler(cli.Application):
    verbose = cli.Flag(["-v", "--verbose"], help = "Enable verbose mode")
    include_dirs = cli.SwitchAttr("-I", list = True, help = "Specify include directories")

    @cli.switch("-loglevel", int)
    def set_log_level(self, level):
        """Sets the log-level of the logger"""
        logging.root.setLevel(level)

    def main(self, *srcfiles):
        print "Verbose:", self.verbose
        print "Include dirs:", self.include_dirs
        print "Compiling:", srcfiles

if __name__ == "__main__":
    MyCompiler.run()

輸出樣例:

$ python simple_cli.py -v -I foo/bar -Ispam/eggs x.cpp y.cpp z.cpp
Verbose: True
Include dirs: ['foo/bar', 'spam/eggs']
Compiling: ('x.cpp', 'y.cpp', 'z.cpp')

參見命令列應用程式

顏色和風格

from plumbum import colors
with colors.red:
    print("This library provides safe, flexible color access.")
    print(colors.bold | "(and styles in general)", "are easy!")
print("The simple 16 colors or",
      colors.orchid & colors.underline | '256 named colors,',
      colors.rgb(18, 146, 64) | "or full rgb colors" ,
      'can be used.')
print("Unsafe " + colors.bg.dark_khaki + "color access" + colors.bg.reset + " is available too.")

輸出樣例:

This library provides safe color access.
Color (and styles in general) are easy!
The simple 16 colors, 256 named colors, or full hex colors can be used.
Unsafe color access is available too.

參見顏色

開發和安裝

該庫在 Github 上開發,非常樂意接受來自使用者的補丁。請使用 GitHub 的內建 issue 跟蹤器報告您遇到的任何問題或提出功能上的需求。該庫在 IMIT 許可下發布。

要求

Plumbum 支援 Python 2.6-3.6 和 PyPy,並且透過 Travis CIAppveyor 持續地在 Linux,Mac 和 Windows 機器上測試。Plumbum 在任何類 Unix 的機器都應該可以正常工作,但是在 Windows 上,你也許需要安裝一個合適的 coreutils 環境並把其加入到你的PATH環境變數中。我推薦 mingw(與 Windows Git 捆綁在一起),但是 cygwin 應該也可以。如果你僅僅是使用 Plumbum 代替 Popen 來執行 Windows 程式,那麼就不需要 Unix 工具了。 注意遠端命令的執行,你需要一個 openSHH 相容的客戶端(同樣與 Windows Git 捆綁在一起)和一個 bash 相容的 shell,也需要在主機上有一個 coreutils 環境。

下載

你可以在 Python Package Index (多種格式)下載該庫,或者直接執行 pip install plumbum。如果你使用 Anaconda,你可以使用 conda install -c conda-forge plumbumconda-forge 通道獲取。

使用者指南

使用者指南涵蓋了 Plumbum 大部分功能,擁有大量的程式碼片段,你可以不用花多少時間即可開始使用。該指南逐漸介紹概念和"語法",因此推薦你按照順序閱讀。一個有效的快速參考指南略。。。

關於

Plumburn 最初的目的是讓本地和遠端程式輕鬆地執行,假設沒有比老的 ssh 更時髦的東西了。在此基礎上,設計了一個檔案系統抽象層,以便能夠無縫地處理本地和遠端檔案。 我有這個想法一段時間了,直到我必須要個給我當前工作的專案寫一個構建指令碼,我決定使用 shell 指令碼,現在是實現它的時候了。Plumbum 誕生自 Path 類的片段和我為 RPyC 寫的 SshContextSshTunnel 類。Path 類是我為前面說的構建系統寫的。當我將兩者與 shell 組合器(因為 shell 指令碼在這裡確實有優勢)組合在一起時,奇蹟就發生了,便產生了Plumbun。

致謝

該專案受到了 Andrew MoffatPBS(現在被稱作 sh)啟發,並且借用了他的一些思想(即像函式一樣看待程式,匯入命令列的技巧)。然而我感覺在 PBS 中有太多的神秘的東西,當我編寫類 shell 程式時,語法不是我想要的。關於這個問題我聯絡了 Andrew,但是他想讓 PBS 保持這種狀態。除此之外,兩個庫走不同的方向,Plumbum 試圖提供一種更合理的方法。

Plumbum 也向 Rotem Yaari 致敬,他為特定的目的建議了一個代號為 pyplatform 的庫,但是尚未實現過。

相關文章