{"id":13398367,"url":"https://github.com/tomerfiliba/plumbum","last_synced_at":"2025-05-13T15:05:05.712Z","repository":{"id":3128734,"uuid":"4156651","full_name":"tomerfiliba/plumbum","owner":"tomerfiliba","description":"Plumbum: Shell Combinators","archived":false,"fork":false,"pushed_at":"2025-04-13T05:10:25.000Z","size":2331,"stargazers_count":2893,"open_issues_count":136,"forks_count":186,"subscribers_count":49,"default_branch":"master","last_synced_at":"2025-04-23T06:53:42.318Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://plumbum.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomerfiliba.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-04-27T08:51:34.000Z","updated_at":"2025-04-21T06:49:52.000Z","dependencies_parsed_at":"2023-02-12T17:16:16.748Z","dependency_job_id":"fc24ccb5-dc78-41b2-99d0-27be70253573","html_url":"https://github.com/tomerfiliba/plumbum","commit_stats":{"total_commits":1138,"total_committers":122,"mean_commits":9.327868852459016,"dds":0.7521968365553603,"last_synced_commit":"6decc98b7b874db4cc7edbb5faf898fc1d2b4dff"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomerfiliba%2Fplumbum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomerfiliba%2Fplumbum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomerfiliba%2Fplumbum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomerfiliba%2Fplumbum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomerfiliba","download_url":"https://codeload.github.com/tomerfiliba/plumbum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250386744,"owners_count":21422026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T19:00:23.962Z","updated_at":"2025-04-23T06:53:47.263Z","avatar_url":"https://github.com/tomerfiliba.png","language":"Python","funding_links":[],"categories":["Python","Process, Thread \u0026 Coroutine","others","Shell","Programming","Infrastructure \u0026 DevOps"],"sub_categories":["C++/C Toolkit","Python"],"readme":".. image:: https://readthedocs.org/projects/plumbum/badge/\n   :target: https://plumbum.readthedocs.io/en/latest/\n   :alt: Documentation Status\n.. image:: https://github.com/tomerfiliba/plumbum/workflows/CI/badge.svg\n   :target: https://github.com/tomerfiliba/plumbum/actions\n   :alt: Build Status\n.. image:: https://coveralls.io/repos/tomerfiliba/plumbum/badge.svg?branch=master\u0026service=github\n   :target: https://coveralls.io/github/tomerfiliba/plumbum?branch=master\n   :alt: Coverage Status\n.. image:: https://img.shields.io/pypi/v/plumbum.svg\n   :target: https://pypi.python.org/pypi/plumbum/\n   :alt: PyPI Status\n.. image:: https://img.shields.io/pypi/pyversions/plumbum.svg\n   :target: https://pypi.python.org/pypi/plumbum/\n   :alt: PyPI Versions\n.. image:: https://img.shields.io/conda/vn/conda-forge/plumbum.svg\n   :target: https://github.com/conda-forge/plumbum-feedstock\n   :alt: Conda-Forge Badge\n.. image:: https://img.shields.io/pypi/l/plumbum.svg\n   :target: https://pypi.python.org/pypi/plumbum/\n   :alt: PyPI License\n.. image:: https://badges.gitter.im/plumbumpy/Lobby.svg\n   :alt: Join the chat at https://gitter.im/plumbumpy/Lobby\n   :target: https://gitter.im/plumbumpy/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n   :alt: Code styled with Black\n   :target: https://github.com/psf/black\n\n\nPlumbum: Shell Combinators\n==========================\n\nEver wished the compactness of shell scripts be put into a **real** programming language?\nSay hello to *Plumbum Shell Combinators*. Plumbum (Latin for *lead*, which was used to create\npipes back in the day) is a small yet feature-rich library for shell script-like programs in Python.\nThe motto of the library is **\"Never write shell scripts again\"**, and thus it attempts to mimic\nthe **shell syntax** (\"shell combinators\") where it makes sense, while keeping it all **Pythonic\nand cross-platform**.\n\nApart from shell-like syntax and handy shortcuts, the library provides local and remote command\nexecution (over SSH), local and remote file-system paths, easy working-directory and environment\nmanipulation, and a programmatic Command-Line Interface (CLI) application toolkit.\nNow let's see some code!\n\n*This is only a teaser; the full documentation can be found at*\n`Read the Docs \u003chttps://plumbum.readthedocs.io\u003e`_\n\nCheat Sheet\n-----------\n\nBasics\n******\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum import local\n    \u003e\u003e\u003e local.cmd.ls\n    LocalCommand(/bin/ls)\n    \u003e\u003e\u003e local.cmd.ls()\n    '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'\n    \u003e\u003e\u003e notepad = local[\"c:\\\\windows\\\\notepad.exe\"]\n    \u003e\u003e\u003e notepad()                                   # Notepad window pops up\n    ''                                              # Notepad window is closed by user, command returns\n\nIn 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!\nYou can also use ``from plumbum.cmd import ls`` as well for accessing programs in the ``PATH``.\n\nPiping\n******\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum.cmd import ls, grep, wc\n    \u003e\u003e\u003e chain = ls[\"-a\"] | grep[\"-v\", r\"\\.py\"] | wc[\"-l\"]\n    \u003e\u003e\u003e print(chain)\n    /bin/ls -a | /bin/grep -v '\\.py' | /usr/bin/wc -l\n    \u003e\u003e\u003e chain()\n    '27\\n'\n\nRedirection\n***********\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum.cmd import cat, head\n    \u003e\u003e\u003e ((cat \u003c \"setup.py\") | head[\"-n\", 4])()\n    '#!/usr/bin/env python3\\nimport os\\n\\ntry:\\n'\n    \u003e\u003e\u003e (ls[\"-a\"] \u003e \"file.list\")()\n    ''\n    \u003e\u003e\u003e (cat[\"file.list\"] | wc[\"-l\"])()\n    '31\\n'\n\nWorking-directory manipulation\n******************************\n\n.. code-block:: python\n\n    \u003e\u003e\u003e local.cwd\n    \u003cLocalWorkdir /home/tomer/workspace/plumbum\u003e\n    \u003e\u003e\u003e with local.cwd(local.cwd / \"docs\"):\n    ...     chain()\n    ...\n    '22\\n'\n\nForeground and background execution\n***********************************\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum import FG, BG\n    \u003e\u003e\u003e (ls[\"-a\"] | grep[r\"\\.py\"]) \u0026 FG         # The output is printed to stdout directly\n    build.py\n    setup.py\n    translations.py\n    \u003e\u003e\u003e (ls[\"-a\"] | grep[r\"\\.py\"]) \u0026 BG         # The process runs \"in the background\"\n    \u003cFuture ['/bin/grep', '\\\\.py'] (running)\u003e\n\nCommand nesting\n***************\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum.cmd import sudo, ifconfig\n    \u003e\u003e\u003e print(sudo[ifconfig[\"-a\"]])\n    /usr/bin/sudo /sbin/ifconfig -a\n    \u003e\u003e\u003e (sudo[ifconfig[\"-a\"]] | grep[\"-i\", \"loop\"]) \u0026 FG\n    lo        Link encap:Local Loopback\n              UP LOOPBACK RUNNING  MTU:16436  Metric:1\n\nRemote commands (over SSH)\n**************************\n\nSupports `openSSH \u003chttp://www.openssh.org/\u003e`_-compatible clients,\n`PuTTY \u003chttp://www.chiark.greenend.org.uk/~sgtatham/putty/\u003e`_ (on Windows)\nand `Paramiko \u003chttps://github.com/paramiko/paramiko/\u003e`_ (a pure-Python implementation of SSH2)\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from plumbum import SshMachine\n    \u003e\u003e\u003e remote = SshMachine(\"somehost\", user = \"john\", keyfile = \"/path/to/idrsa\")\n    \u003e\u003e\u003e r_ls = remote[\"ls\"]\n    \u003e\u003e\u003e with remote.cwd(\"/lib\"):\n    ...     (r_ls | grep[\"0.so.0\"])()\n    ...\n    'libusb-1.0.so.0\\nlibusb-1.0.so.0.0.0\\n'\n\nCLI applications\n****************\n\n.. code-block:: python\n\n    import logging\n    from plumbum import cli\n\n    class MyCompiler(cli.Application):\n        verbose = cli.Flag([\"-v\", \"--verbose\"], help = \"Enable verbose mode\")\n        include_dirs = cli.SwitchAttr(\"-I\", list = True, help = \"Specify include directories\")\n\n        @cli.switch(\"--loglevel\", int)\n        def set_log_level(self, level):\n            \"\"\"Sets the log-level of the logger\"\"\"\n            logging.root.setLevel(level)\n\n        def main(self, *srcfiles):\n            print(\"Verbose:\", self.verbose)\n            print(\"Include dirs:\", self.include_dirs)\n            print(\"Compiling:\", srcfiles)\n\n    if __name__ == \"__main__\":\n        MyCompiler.run()\n\nSample output\n+++++++++++++\n\n::\n\n    $ python3 simple_cli.py -v -I foo/bar -Ispam/eggs x.cpp y.cpp z.cpp\n    Verbose: True\n    Include dirs: ['foo/bar', 'spam/eggs']\n    Compiling: ('x.cpp', 'y.cpp', 'z.cpp')\n\nColors and Styles\n-----------------\n\n.. code-block:: python\n\n    from plumbum import colors\n    with colors.red:\n        print(\"This library provides safe, flexible color access.\")\n        print(colors.bold | \"(and styles in general)\", \"are easy!\")\n    print(\"The simple 16 colors or\",\n          colors.orchid \u0026 colors.underline | '256 named colors,',\n          colors.rgb(18, 146, 64) | \"or full rgb colors\",\n          'can be used.')\n    print(\"Unsafe \" + colors.bg.dark_khaki + \"color access\" + colors.bg.reset + \" is available too.\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomerfiliba%2Fplumbum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomerfiliba%2Fplumbum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomerfiliba%2Fplumbum/lists"}