Plumbum: Shell Combinators

Overview
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

>> notepad() # Notepad window pops up '' # Notepad window is closed by user, command returns">
>>> 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

>> print(chain) /bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l >>> chain() '27\n'">
>>> 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

>> (ls["-a"] > "file.list")() '' >>> (cat["file.list"] | wc["-l"])() '31\n'">
>>> 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

>> (ls["-a"] | grep[r"\.py"]) & BG # The process runs "in the background" ">
>>> 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

>> (sudo[ifconfig["-a"]] | grep["-i", "loop"]) & FG lo Link encap:Local Loopback UP LOOPBACK RUNNING MTU:16436 Metric:1">
>>> 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)

>> 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'">
>>> 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.")
Comments
  • fix: glob characters in local paths

    fix: glob characters in local paths

    Addresses only the local part of https://github.com/tomerfiliba/plumbum/issues/481 with minimal changes and no new dependencies. I haven't worked with the remote parts of plumbum, sorry.

    opened by wtanksleyjr 19
  • Release 1.6.8 (and 1.7 notice)

    Release 1.6.8 (and 1.7 notice)

    We need to make a release fairly soon, while Travis is still able to run Python 2.6. I'd like to make a 1.6.8 release, and then drop Python 2.6 and non-setuptools builds from master. This would start on the 1.7 work; any critical fixes or easy patches could be backported to a 1.6 branch if needed, but 1.7 would not support Python 2.6. This should allow some cleanup as well. If you are using Python 2.6, which people on RHEL6 based systems might be, plumbum would need to be restricted to <1.7.

    Todo:

    • [ ] Check translations
    • [ ] Fill out changelog
    • [ ] Evaluate old PRs
    opened by henryiii 17
  • Overzealous string quoting / space escaping

    Overzealous string quoting / space escaping

    Hi,

    I'm using plumbum 1.4.1 to call reflector on Arch Linux. I'm not sure what the problem is, but somewhere along the way, way too much string/space escaping happens.

    Here is code to reproduce the problem:

    #!/usr/bin/env python3
    from itertools import chain
    from plumbum.cmd import reflector, sudo
    
    def update_mirrorlist(countries=['United States', 'Canada']):
        countries = list(chain(*[('--country', country) for country in countries]))
        print(sudo[reflector['--save', '/etc/pacman.d/mirrorlist', '--sort', 'score', '--latest', '30', countries]])
        sudo(reflector['--save', '/etc/pacman.d/mirrorlist', '--sort', 'score', '--latest', '30', countries])
    
    if __name__ == '__main__':
        update_mirrorlist()
    

    This yields the output

    /usr/bin/sudo /usr/bin/reflector --save /etc/pacman.d/mirrorlist --sort score --latest 30 --country 'United States' --country Canada
    

    which looks perfect. If I run that printed command exactly, I get the desired result. However, that is not what gets run by the final line in update_mirrorlist. The generated mirrorlist does not include anything from the United States, and the comments report that the command actually run was

    reflector --save /etc/pacman.d/mirrorlist --sort score --latest 30 --country ''"'"'United States'"'"'' --country Canada
    
    opened by AndydeCleyre 16
  • EOFError connecting to RHEL5 / RHEL6 remotes

    EOFError connecting to RHEL5 / RHEL6 remotes

    I'm currently experiencing issues setting up remotes towards RHEL5 & 6 remotes. I'm getting a stack trace with EOFError (see below). plumbum version 1.4.0. Python 3.2.3 & 3.3.4

    Connecting to remote Mac OS X 10.9.1 and Ubuntu 12.04.4 LTS works fine.

    debug1: Local version string SSH-2.0-OpenSSH_6.5
    

    RHEL 5 OpenSSH

    debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
    debug1: match: OpenSSH_4.3 pat OpenSSH_4* compat 0x00000000
    

    RHEL 6 OpenSSH

    debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
    debug1: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000000
    

    OS X 10.9.1 OpenSSH

    debug1: Remote protocol version 2.0, remote software version OpenSSH_6.2
    debug1: match: OpenSSH_6.2 pat OpenSSH* compat 0x04000000
    

    Ubuntu 12.04 OpenSSH

    debug1: Remote protocol version 2.0, remote software version OpenSSH_5.9p1 Debian-5ubuntu1.1
    debug1: match: OpenSSH_5.9p1 Debian-5ubuntu1.1 pat OpenSSH_5* compat 0x0c000000
    

    Traceback

    Traceback (most recent call last):
      File "./plum-e.py", line 15, in <module>
        with SshMachine(ssh_host, user=ssh_user, ssh_command=ssh, scp_command=scp, keyfile=ssh_key_path) as remote:
      File "/usr/lib/python3.2/site-packages/plumbum/machines/ssh_machine.py", line 101, in __init__
        BaseRemoteMachine.__init__(self, encoding = encoding, connect_timeout = connect_timeout)
      File "/usr/lib/python3.2/site-packages/plumbum/machines/remote.py", line 124, in __init__
        self._session = self.session()
      File "/usr/lib/python3.2/site-packages/plumbum/machines/ssh_machine.py", line 145, in session
        self.encoding, isatty, self.connect_timeout)
      File "/usr/lib/python3.2/site-packages/plumbum/machines/session.py", line 141, in __init__
        self.run("")
      File "/usr/lib/python3.2/site-packages/plumbum/machines/session.py", line 224, in run
        return run_proc(self.popen(cmd), retcode)
      File "/usr/lib/python3.2/site-packages/plumbum/commands/processes.py", line 186, in run_proc
        stdout, stderr = proc.communicate()
      File "/usr/lib/python3.2/site-packages/plumbum/machines/session.py", line 92, in communicate
        line = pipe.readline()
      File "/usr/lib/python3.2/site-packages/plumbum/machines/session.py", line 42, in readline
        raise EOFError()
    EOFError
    
    Bug 
    opened by eripa 15
  • Redirecting stdout/stderr without using

    Redirecting stdout/stderr without using "& FG or & BG constructs"

    I love the ability to create pipelines and to do file redirections in Plumbum with the bash-like syntax, but I'm not a big fan of the & FG/& BG constructs for actually running the pipelines, because I feel that they're an unintuitive syntax. I feel that there should be an explicit method call to run these commands, and indeed my IDE treats these statements as doing nothing: screenshot from 2017-11-03 15-50-02

    Is there a nice way to say "run this pipeline, with these redirections", without using these & constructs? I've looked at run() and popen(), but run() seems to return the entire stdout, which worries me because I'm doing large data processing and I don't want python to ever have to see this data. popen() is also more complex than I need, since you have to call communicate, and when you do so it still returns stdout, which I don't want.

    New feature 
    opened by multimeric 11
  • image.py: fix old-style(?) relative import statement

    image.py: fix old-style(?) relative import statement

    This fixes #365. I can't actually find when this syntax became illegal, but this replacement works both in Python 2.7 and 3.6 whereas the original doesn't.

    As I wrote in #365, this patch unbreaks installs under versions of pip that have a hard dependency on the py->pyc step succeeding.

    opened by tkluck 10
  • Add localization functions and russian localization

    Add localization functions and russian localization

    This PR fixes #335 - It adds gettext localization to all strings that are used in Application output. Also as a test I've written russian localization. Any other language can be easily added. This should be tested on py2.x and on Windows.

    opened by ASMfreaK 10
  • shquote breaks certain sudo commands

    shquote breaks certain sudo commands

    Hi, when using some sudo commands I found out that they were failing where they shouldn't have. E.g.:

    from plumbum.cmd import sudo, yum
    
    sudo(yum['install']['rubygem(rails)'])
    

    This fails, because rubygem(rails) gets overquoted by formulate (which calls shquote). This ends up formulated like this:

    ['/usr/bin/sudo', '/usr/bin/yum', 'install', "'rubygem(rails)'"]
    

    So yum in fact gets "'rubygem(rails)'" on commandline (because Popen puts the outer quotes there.

    I think that the problem can be solved by adding '(' and ')' to _safechars, which seems ok to me, but I'm not sure of other consequences of this. Any other options how to solve this?

    Thanks.

    V1.2 
    opened by bkabrda 10
  • fix handling of env-vars passed to plumbum Commands; support new with_cwd

    fix handling of env-vars passed to plumbum Commands; support new with_cwd

    Fix handling of env-vars passed to plumbum BoundEnvCommands: - don't use the non-threadsafe and session-dependent .env() context manager - sync popen support for 'env' param in all machine impls: local/ssh/paramiko - add .with_cwd() to complement .with_env()

    opened by koreno 9
  • Make argument type error messages use `__str__` method of `Predicate`s

    Make argument type error messages use `__str__` method of `Predicate`s

    Previous behavior looks like this

    Error: Argument of output expected to be <plumbum.cli.switches.Predicate object at 0x10ce91c10>, not 'requirements.txt':
            ValueError('output is a file, should be a directory',)
    

    now looks like this

        Error: Argument of output expected to be 'MakeDirectory', not 'requirements.txt':
            ValueError('output is a file, should be a directory',)
    

    when checking a Predicate.

    opened by gmarceau 9
  • Shell command advice

    Shell command advice

    Hi Tomer, what would be a good way to implement this command

    diff <(sed 's/pattern//g' file1) <(sed 's/pattern//g' file2)
    

    where pattern, file1 and file2 would change from one execution to another?

    opened by AntoineD 9
  • recursive globbing not work like pathlib

    recursive globbing not work like pathlib

    recursive globbing not work like pathlib. Is this intented?

    if cwd is /home/yakkle/tmp has subdirectory foo/bar, and has file sample.zip in foo/bar :

    >>> local.cwd // "**/*.zip"
    []
    >>> 
    

    will show empty list.

    if base path is /home/yakkle/tmp/foo:

    >>> local.cwd["foo"] // "**/*.zip"
    [<LocalPath /home/yakkle/tmp/foo/bar/sample.zip>]
    >>> 
    

    will show found result. but it only 1 depth search. not recursive.


    python docs says :

    The “**” pattern means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing:

    https://docs.python.org/3.9/library/pathlib.html?highlight=mkdir#pathlib.Path.glob

    opened by yakkle 0
  • keyfile is ignored by SshMachine

    keyfile is ignored by SshMachine

    I can't get ssh with key authentication to work. The keyfile attribute seems to be ignored and the program keeps asking for user password. There's even no difference when I specify invalid path to the key file. There's no quick way to examine the ssh command being used as plumbum doesn't have debug facilities (https://github.com/tomerfiliba/plumbum/issues/474).

    The key file is accessible and can be read in the same Python script.

    The code is basically with SshMachine('[email protected]', keyfile='./ssh/keyfile') as remote_box:

    Environment: Debian 11 Python 3.9.2 OpenSSH 8.4p1 Plumbum 1.7.2

    opened by youk 0
  • byte parameters and command names should be used as is

    byte parameters and command names should be used as is

    for example:

    print(plumbum.local['echo'](b'test'))

    should result in

    test

    but instead it results in:

    b'test'

    byte objects are not even supported in command names:

    plumbum.local[b'echo']

    results in a type error

    TypeError: a bytes-like object is required, not 'str'

    in plumbum/machines/local.py:243

    opened by vcalv 0
  • Run commands with environment from global environment

    Run commands with environment from global environment

    Hi, thanks for the great library. I have a question.

    As far as I understand, when you run commands via local object, they read environ from frozen local.env object. Is there a way to change that behavior and to make them use os.environ instead?

    The issue I have - I have other python code I don't have quite a control of that changes os.environ, so it would be more convenient if local would use os.environ instead of saved local.env.

    Thank you.

    opened by willir 0
  • Set PR_SET_PDEATHSIG on for all commands

    Set PR_SET_PDEATHSIG on for all commands

    Hi, thanks for the great library. I have a question - is it possible to set PR_SET_PDEATHSIG on Linux for all running commands?

    When I use subprocess myself, I do it like:

    SIGHUP = 1
    PR_SET_PDEATHSIG = 1
    libc = ctypes.CDLL("/lib64/libc.so.6")
    
    
    def set_pdeathsig_cb():
        ppid = os.getpid()
    
        def cb():
            res = libc.prctl(PR_SET_PDEATHSIG, SIGHUP)
            if res != 0:
                print(f"Fail to set PR_SET_PDEATHSIG. Return value: {res}", file=sys.stderr)
                sys.exit(1)
            if os.getppid() != ppid:
                print("Parent process has already died", file=sys.stderr)
                sys.exit(1)
    
        return cb
    
    with subprocess.Popen(cmd, preexec_fn=set_pdeathsig_cb()) as p:
        ...
    

    Thank you.

    opened by willir 0
Releases(v1.8.1)
  • v1.8.1(Jan 2, 2023)

    This release moves to using a pyproject.toml based packaging backend (hatchling).

    What's Changed

    • local: Accept path-like objects (#627)
    • Move the build backend to hatchling and hatch-vcs. Users should be unaffected. Third-party packaging may need to adapt to the new build system. (#607)

    New Contributors

    • @doronz88 made their first contribution in https://github.com/tomerfiliba/plumbum/pull/627

    Full Changelog: https://github.com/tomerfiliba/plumbum/compare/v1.8.0...v1.8.1

    Source code(tar.gz)
    Source code(zip)
  • v1.8.0(Oct 6, 2022)

    This is the final release series for Python 3.6.

    • Drop Python 2.7 and 3.5 support, add 3.11 support #573
    • Lots of extended checks and fixes for problems exposed.
    • Color: support NO_COLOR/FORCE_COLOR #575
    • Commands: New iter_lines buffer_size parameter #582
    • Commands: cache remote commands #583
    • SSH: Support reverse tunnels and dynamically allocated ports #608
    • CLI: add Set(..., all_markers={"*", "all"}) and fix support for other separators #619
    • CLI: support future annotations #621
    • Color: fix the ABC #617
    • Exceptions: fix for exception pickling #586
    • Fix for StdinDataRedirection and modifiers #605

    New Contributors

    • @damani42 made their first contribution in https://github.com/tomerfiliba/plumbum/pull/585
    • @pylanglois made their first contribution in https://github.com/tomerfiliba/plumbum/pull/588
    • @andriyor made their first contribution in https://github.com/tomerfiliba/plumbum/pull/593
    • @jesteria made their first contribution in https://github.com/tomerfiliba/plumbum/pull/605

    Full Changelog: https://github.com/tomerfiliba/plumbum/compare/v1.7.2...v1.8.0

    Source code(tar.gz)
    Source code(zip)
  • v1.7.2(Dec 23, 2021)

    This is the final release for Python 2 and 3.5.

    • Commands: avoid issue mktemp issue on some BSD variants (#571)
    • Better specification of dependency on pywin32( #568)
    • Some DeprecationWarnings changed to FutureWarnings (#567)
    Source code(tar.gz)
    Source code(zip)
  • v1.7.1(Nov 23, 2021)

    • Paths: glob with local paths no longer expands the existing path too (#552)
    • Paramiko: support reverse tunnels (#562)
    • SSHMachine: support forwarding Unix sockets in .tunnel() (#550)
    • CLI: Support COLOR_GROUP_TITLES (#553)
    • Fix a deprecated in Python 3.10 warning (#563)
    • Extended testing and checking on Python 3.10 and various PyPy versions. Nox is supported for easier new-user development.
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Feb 8, 2021)

    • Commands: support .with_cwd() (#513)
    • Commands: make iter_lines deal with decoding errors during iteration (#525)
    • Commands: fix handling of env-vars passed to plumbum BoundEnvCommands (#513)
    • Commands: fix support for win32 in iter_lines (#500)
    • Paths: fix incorrect __getitem__ method in Path (#506)
    • Paths: Remote path stat had odd OSError (#505)
    • Paths: Fix RemotePath.copy() (#527)
    • Paths: missing __fspath__ added (#498)
    • SSH: better error reporting on SshSession error (#515)
    • Internal: redesigned CI, major cleanup to setuptools distribution, Black formatting, style checking throughout.

    If you install from the auto-generated tarball for Git releases, you should either use SETUPTOOLS_SCM_PRETEND_VERSION=${pkgver} pip install . (where pkgver is the package version, 1.7.0 in this case), or (not recommended) install setuptools_scm before running SETUPTOOLS_SCM_PRETEND_VERSION=${pkgver} python setup.py install. PyPI SDists have the version file already, and git checkouts will get the version from git tags.

    Source code(tar.gz)
    Source code(zip)
  • v1.6.9(Mar 23, 2020)

    • Last version to support Python 2.6; added python_requires (#507)
    • Paths: Fix bug with subscription operations (#498), (#506)
    • Paths: Fix resolve (#492)
    • Commands: Fix resolve (#491)
    • Commands: Add context manager on popen (#495)
    • Several smaller fixes (#500), (#505)
    Source code(tar.gz)
    Source code(zip)
  • v1.6.8(Oct 30, 2019)

    1.6.8

    • Exceptions: Changed ProcessExecutionError's formatting to be more user-friendly #456
    • Commands: support for per-line timeout with iter_lines #454
    • Commands: support for piping stdout/stderr to a logger #454
    • Paths: support composing paths using subscription operations #455
    • CLI: Improved 'Set' validator to allow non-string types, and CSV params #452
    • TypedEnv: Facility for modeling environment-variables into python data types #451
    • Commands: execute local/remote commands via a magic .cmd attribute #450
    Source code(tar.gz)
    Source code(zip)
  • v1.6.7(Aug 10, 2018)

    • Commands: Added run_* methods as an alternative to modifiers #386
    • CLI: Added support for ALLOW_ABREV #401
    • CLI: Added DESCRIPTION_MORE, preserves spacing #378
    • Color: Avoid throwing error in atexit in special cases (like pytest) #393
    • Including Python 3.7 in testing matrix.
    • Smaller bugfixes and other testing improvements.
    Source code(tar.gz)
    Source code(zip)
A useful and easy to use Terminal Timer made with Python.

Terminal SpeedCubeTimer Installation ¡No requirements! Just Download and play Usage Starts timer.py and you will see this. python timer.py Scramble

Achalogy 5 Dec 22, 2022
Textual: a TUI (Text User Interface) framework for Python inspired by modern web development

Textual Textual is a TUI (Text User Interface) framework for Python inspired by

17.1k Jan 04, 2023
A command-line utility that, given a markdown file, checks whether all its links work.

A command-line utility written in Python that checks validity of links in a markdown file.

Teclado 2 Dec 08, 2021
stonky is a simple command line dashboard for monitoring stocks.

stonky is a simple command line dashboard for monitoring stocks.

Jessy Williams 228 Dec 14, 2022
A simple Python CLI tool that draws routes/paths on a given map.

Map Router A simple Python CLI tool that draws routes/paths on a given map. Index Installation Usage Docs Why? License Support Installation Coming soo

Pedro Morim 1 Nov 07, 2021
Booky - A command line utility for bookmarking files on your terminal!

Booky A command line utility for bookmarking files for quick access With it you can: Bookmark and delete your (aliases of) files at demand Launch them

Pran 1 Sep 11, 2022
GoogleFormSpammer - A simple CLI script to spam Google Forms used by Crypto Wallet scammers to collect stolen data

GoogleFormSpammer - A simple CLI script to spam Google Forms used by Crypto Wallet scammers to collect stolen data

14 Dec 17, 2022
Interactive Python interpreter for executing commands within Node.js

Python Interactive Interactive Python interpreter for executing commands within Node.js. This module provides a means of using the Python interactive

Louis Lefevre 2 Sep 21, 2022
vimBrain is a brainfuck-based vim-inspired esoteric programming language.

vimBrain vimBrain is a brainfuck-based vim-inspired esoteric programming language. vimBrainPy Currently, the only interpreter available is written in

SalahDin Ahmed 3 May 08, 2022
A basic molecule viewer written in Python, using curses; Thus, meant for linux terminals

asciiMOL A basic molecule viewer written in Python, using curses; Thus, meant for linux terminals. This is an alpha version, featuring: Opening defaul

Dominik Behrens 328 Dec 11, 2022
Oil is a new Unix shell. It's our upgrade path from bash to a better language and runtime

Oil is a new Unix shell. It's our upgrade path from bash to a better language and runtime. It's also for Python and JavaScript users who avoid shell!

2.4k Jan 08, 2023
Access hacksec.in from your command-line

Access hacksec.in from your command-line

hacksec.in 3 Oct 26, 2022
Terminal-based keyboard testing

kbdtest kbdtest is a simple Python program that tests keyboard input using an interactive, terminal-based, visual keyboard display. It was originally

Ruunyox 12 Jul 19, 2022
Doing set operations on files considered as sets of lines

CLI tool that can be used to do set operations like union on files considering them as a set of lines. Notes It ignores all empty lines with whitespac

Partho 11 Sep 06, 2022
pyNPS - A cli Linux and Windows Nopaystation client made with python 3 and wget

Currently, all the work is being done inside the refactoring branch. pyNPS - A cli Linux and Windows Nopaystation client made with python 3 and wget P

Everton Correia 45 Dec 11, 2022
Python wrapper and CLI utility to render LaTeX markup and equations as SVG using dvisvgm and svgo.

latex2svg Python wrapper and CLI utility to render LaTeX markup and equations as SVG using dvisvgm and svgo. Based on the original work by Tino Wagner

Matthias C. Hormann 4 Feb 18, 2022
Install python modules from pypi from a previous date in history

pip-rewind is a command-line tool that can rewind pypi module versions (given as command-line arguments or read from a requirements.txt file) to a previous date in time.

Amar Paul 4 Jul 03, 2021
A simple note taker CLI program written in python

note-taker A simple note taker program written in python This allows you to snip your todo's, notes, and your tasks easily without extra charges Requi

marcusz 4 Nov 02, 2021
NudeNet wrapper made to provide a simple cli interface to the library

Nudenet Wrapper. Small warpper script for NudeNet Made to provide a small and easy to use cli interface with the library. You can indicate a single im

1 Oct 20, 2021
PyDropper - pick colors everywhere

PyDropper - pick colors everywhere Downloads Settings PyDropper is an eyedropper

Herman Brunberg 2 Jan 04, 2022