Skip to main content

Plumbum: shell combinators library

Project description

Documentation Status Build Status Coverage Status PyPI Status PyPI Versions Conda-Forge Badge PyPI License Join the chat at https://gitter.im/plumbumpy/Lobby Code styled with Black

Plumbum: Shell Combinators

Ever wished the compactness of shell scripts be put into a real programming language? Say hello to Plumbum Shell Combinators. Plumbum (Latin for lead, which was used to create pipes back in the day) is a small yet feature-rich library for shell script-like programs in Python. The motto of the library is “Never write shell scripts again”, and thus it attempts to mimic the shell syntax (“shell combinators”) where it makes sense, while keeping it all Pythonic and cross-platform.

Apart from shell-like syntax and handy shortcuts, the library provides local and remote command execution (over SSH), local and remote file-system paths, easy working-directory and environment manipulation, and a programmatic Command-Line Interface (CLI) application toolkit. Now let’s see some code!

This is only a teaser; the full documentation can be found at Read the Docs

Cheat Sheet

Basics

>>> from plumbum import local
>>> local.cmd.ls
LocalCommand(/bin/ls)
>>> local.cmd.ls()
'build.py\nCHANGELOG.rst\nconda.recipe\nCONTRIBUTING.rst\ndocs\nexamples\nexperiments\nLICENSE\nMANIFEST.in\nPipfile\nplumbum\nplumbum.egg-info\npytest.ini\nREADME.rst\nsetup.cfg\nsetup.py\ntests\ntranslations.py\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
''                                              # Notepad window is closed by user, command returns

In the example above, you can use local["ls"] if you have an unusually named executable or a full path to an executable. The local object represents your local machine. As you’ll see, Plumbum also provides remote machines that use the same API! You can also use from plumbum.cmd import ls as well for accessing programs in the PATH.

Piping

>>> from plumbum.cmd import ls, grep, wc
>>> chain = ls["-a"] | grep["-v", r"\.py"] | wc["-l"]
>>> print(chain)
/bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l
>>> chain()
'27\n'

Redirection

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

Working-directory manipulation

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

Foreground and background execution

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

Command nesting

>>> from plumbum.cmd import sudo, ifconfig
>>> 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

Remote commands (over SSH)

Supports openSSH-compatible clients, PuTTY (on Windows) and Paramiko (a pure-Python implementation of SSH2)

>>> 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"])()
...
'libusb-1.0.so.0\nlibusb-1.0.so.0.0.0\n'

CLI applications

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()
Sample output
$ 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')

Colors and Styles

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.")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plumbum-1.7.2.tar.gz (323.1 kB view details)

Uploaded Source

Built Distribution

plumbum-1.7.2-py2.py3-none-any.whl (117.8 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file plumbum-1.7.2.tar.gz.

File metadata

  • Download URL: plumbum-1.7.2.tar.gz
  • Upload date:
  • Size: 323.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for plumbum-1.7.2.tar.gz
Algorithm Hash digest
SHA256 0d1bf908076bbd0484d16412479cb97d6843069ee19f99e267e11dd980040523
MD5 83916eed4814f34b458635667370fdb1
BLAKE2b-256 c8d8aa3973de6151ae322e3f0dd4f2befcece695ed7c09d49536d8174ef80a9c

See more details on using hashes here.

File details

Details for the file plumbum-1.7.2-py2.py3-none-any.whl.

File metadata

  • Download URL: plumbum-1.7.2-py2.py3-none-any.whl
  • Upload date:
  • Size: 117.8 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for plumbum-1.7.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 0bbf431e31da988405de2fb36c3226f09c0c9cdf69c8480f8997f4b94b7370a1
MD5 c8f3fc8a87fd441be02cf67b81a0cbb9
BLAKE2b-256 f57f4e93e5e1c13261966ea553cb4368599902e4fbf6f7dcad3ec16695a45718

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page