
Security News
minimatch Patches 3 High-Severity ReDoS Vulnerabilities
minimatch patched three high-severity ReDoS vulnerabilities that can stall the Node.js event loop, and Socket has released free certified patches.
aush
Advanced tools
Pythonic subprocess library
aush is a Python library to make calling other programs and getting their output as easy as possible. It's intended to be the best possible melding of shell scripting and Python. It's aushome.
Command line programs are basically “functions” available to call from any other language, whose signature looks like: list[str] -> (code: smallint, stdout: stream, stedrr: stream). That's what calls like execve are doing underneath.
The goal of this library is to make calling those functions as natural as possible within Python.
So often I've found myself writing a small Bash/shell script that just calls some programs and maybe does some conditionals. Naturally, it has to start with
#!/usr/bin/env bash
set -Eeuxo pipefail
for a "strict mode" that has some of the same failure properties you expect a program to have, such as that your program doesn't just keep running when a command fails, it won't silently proceed if you use undeclared variables, and so on.
Then it frequently occurs to want to do something "hard" in shell, like string processing or data structures or even command-line argument parsing.
Python has argparse in the stdlib, I don't want to mess with getopt.
I want to be able to bust out some Pandas DataFrames or Requests requests, read json or whatever.
So often when I start with Bash, I wind up transitioning the script to Python, and that often feels terrible.
Pipes become an unnatural operation.
I can't just "redirect to a file" I need to know how to call subprocess.run to capture stdout (there are a few different ways), open and close the file, and so on.
Instead, aush makes the transition from shell to Python feel better.
Here's the origin thread on lobste.rs.
pip install aush
I recently make a create-python program that will initialize a Python project the same way every time, as a Poetry project with the same set of default dependencies, linters, and so on.
At first I created a shell script. Here's a portion:
poetry init \
--no-interaction \
--name="$1" \
--author="$(git config --get user.name)" \
--dev-dependency=pytest \
--dev-dependency=ipython \
--dev-dependency=pylint \
--dev-dependency=mypy \
--dev-dependency=black \
--dev-dependency=pudb
poetry install
Here's how that converts to Python:
cmd = ['git', 'config', '--get', '--global', 'user.name']
username = run(cmd, check=True, capture_output=True, text=True).stdout.strip()
cmd = [
'poetry', 'init',
'--no-interaction',
'--name', sys.argv[1],
'--author', username,
'--dev-dependency=pytest',
'--dev-dependency=ipython',
'--dev-dependency=pylint',
'--dev-dependency=mypy',
'--dev-dependency=black',
'--dev-dependency=pudb',
]
run(cmd, check=True)
run(['poetry', 'install'], check=True)
Here's how that looks now using aush:
poetry.init(
no_interaction = True,
name = args.name,
author = git.config(get='user.name'),
dev_dependency = ['pytest', 'ipython', 'pylint', 'mypy', 'black', 'pudb'],
)
poetry.install()
I think that finally feels better than either shell or Python alone. Feel free to look at create-python's history where I convert it from shell to Python and try various libraries along the way.
aush has Commands and Results. You make a base command like:
from aush import echo, git, python3
Then, any new command is immutably created from another command by either dot or indexing notation:
git.init()
echo("*.sqlite3") > '.gitignore'
git.add(all=True)
git.commit(m="Initial commit")
Here's an example of explicitly creating a command from another using index notation:
django_manage = python3["manage.py"]
django_manage.startapp(args.name)
django_manage.migrate()
django_manage.createsuperuser(
noinput = True,
username = "admin",
email = git.config(get='user.email'),
_env = dict(DJANGO_SUPERUSER_PASSWORD='password'),
)
Here's how that call to createsuperuser looks in equivalent shell:
DJANGO_SUPERUSER_PASSWORD='password' python3 manage.py createsuperuser \
--noinput \
--username admin \
--email "$(git config --get=user.email)"
Note that, like shell, in aush you don't have to manually merge in os.environ if you want to add new things to the environment.
A program gets executed when a function call () is made on a Command.
That returns a Result.
The result has .code, .stdout, and .stderr members to get the results of running the command.
Using the Result you can also redirect stdout to a file with result > 'filename', bool(result) indicates success or failure of the command, and more.
aush calls follow the following conventions:
str), it is repeatedIf the conventions don't do what you want, you can always fall back to passing exactly the strings you want, positionally, in the list way of creating commands.
aush has a few tricks when used as a module:
$ echo "red: #ff0000 green: #0f0 blue: #00F" | python -m aush -s
prints:
red: #ff0000 [ ] green: #0f0 [ ] blue: #00F [ ]
Pipe a css file to aush to display its color values.
If you want to see a specific color:
python -m aush -c 800080
800080:
aush should provide the most convenient way to write "shell scripts"aush can be useful for calling subprocesses in your programs, and help write safer programs that interact with subprocesses, and bigger "shell scripts" than you would otherwiseaush to be a command-line program itself that does something? Maybe when called as a module it can provide testing utilities like my argv or randomtextgenerator. Maybe an "aush script" could find a way to automatically import anything not found in python space and try to run it? That way you can avoid the 'from aush import a million things' and turn logging on, etc.aush is not a new language or an interactive shell; it's just a Python libraryQ. Pronunciation?
A. It's pronounced "awwsh" ("au" as in "audible").
Q. Where does the name come from?
A. Originally I named it "autoshell", but when I went to put it on PyPI I found "autoshell" was taken, while the shorter present name wasn't.
FAQs
Pythonic subprocess library
We found that aush demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
minimatch patched three high-severity ReDoS vulnerabilities that can stall the Node.js event loop, and Socket has released free certified patches.

Research
/Security News
Socket uncovered 26 malicious npm packages tied to North Korea's Contagious Interview campaign, retrieving a live 9-module infostealer and RAT from the adversary's C2.

Research
An impersonated golang.org/x/crypto clone exfiltrates passwords, executes a remote shell stager, and delivers a Rekoobe backdoor on Linux.