pybashify
Ever wanted to use bash scripts but they look like a bunch of mumbo jumbo? You may have tried the python versions, but they aren't practical when you actually want to run bash, but it's a pain in the neck to actually write that.
That's where pybashify comes in: It allows you to write bash scripts using python whilst compiling them to bash using a template syntax within a bash script that follows the same conventions as regular bash.
In other words, you get to seamlessly interop bash and python! Offload the more complex portions to python, while letting bash do the simple things.
Think of this like a bash template to full bash script compilation that occurs.
And ALL the bash code you write with the template syntax is not only COMPLETELY VALID bash scripting BY ITSELF (which means now you can test just the bash portion without running the python portion; also gives a good separation of concerns at times) but now you are able to write much cleaner code to host on a curl link!
Oh and another side effect of the fact that templates are 100% valid bash: your editor has syntax highlighting for this!
Wait, so you're hijacking existing bash features and repurposing them to work for interoperating with Python scripts?
Yes. It's not that bad though, since the features it repurposes are features that nobody uses in bash anyway, such as the declare keyword.
And even if it were to matter, you have CLI options to mitigate this.
Installation
pip install pybashify
Building from source
pixi run build
Usage
First, create a bash script. This will serve as your template for the real bash script that you will generate.
Then, in the bash script, at its simplest level, you can do this (I'm putting a few variations):
declare BASHIFY_EXECUTE="my.python.module"
declare BASHIFY_EXECUTE='my.python.module'
declare BASHIFY_EXECUTE=my.python.module
declare BASHIFY_EXECUTE = "my.python.module"
...you get the idea.
Then, you can run:
bashify template.sh [--out full_script.sh] [--compat] [--compat-prefix="PY"]
And NOW, a new shell script should be generated with all the same things your original had, except now the area where BASHIFY_EXECUTE was is now replaced with the execution of said python code. This is VERY useful for having users curl.
But wait, there's more!
The example above is functionally equivalent to:
declare my.python.module
declare BASHIFY_EXECUTE
Now why are there 2 ways to do this? Because you can do this:
declare my.python.module
declare my.other.python.module
declare BASHIFY_EXECUTE
This will execute BOTH modules back-to-back inside BASHIFY_EXECUTE. And yes that means order matters. my.python.module will be executed first, followed by my.other.python.module.
You can have the declarations wherever you want, as long as they follow a specific order. However, the position of BASHIFY_EXECUTE DOES matter as that will be where they ultimately aggregate.
This is cool, but I don't like shell features being hijacked
Well you're in luck!
What you need to do to mitigate this is run:
bashify my_script.sh --compat
and then in your my_script.sh, you would do:
declare PY.BASHIFY_EXECUTE=my.python.module
or
declare PY.my.python.module
declare PY.BASHIFY_EXECUTE
Obviously, you can also modify the prefix with the --compat-prefix flag.
Compiled Outputs
You can just have your template be my_script.template.sh and if you run it without specifying an output, it will have the compiled version be my_script.sh.
If you do not use this notation and still go default without specifying an output script, it will by default do my_script_template-compiled.sh if your script input was my_script_template.sh.
Alright, I'm done yapping. Have a nice day, remember to stay hydrated, and definitely remember that I use blendOS btw 😈 🔥 💯
Raw Reference
Without compat mode:
declarerefers to a python module- the name of the variable is the python module (in the same way you import my.python.module)
- there should not be a value
- order is inferred by the order in which your declares are. And yes you can mix them but it is not recommended
- aside from the order of the declares, the positioning of them in the file does not matter as they will be deleted in the compiled version
- The positioning of your final python script declaration, however, DOES matter.
- Use
declare BASHIFY_EXECUTEfor where you want to execute the Python code. However, as stated above, POSITIONING MATTERS - Note that none of these
declares will work if they are on the same line separated with semicolons. might add that feature later if yall want but right now eachdeclarerequires its own line - It should also be scoped globally (meaning that it can't be within an if statement)
- There can only be a single
BASHIFY_EXECUTE. If there are multiple, it will default to the last one
With compat mode:
- Same as without compat mode except all
declares are prefixed withcompat_prefix. By default, it is "PY", so you'd prefix like so: PY.my.python.module - This ALSO applies to the execution directive. By default, it would be:
declare PY.BASHIFY_EXECUTE - This means that
declareby default is not hijacked
Another Caveat:
- For system packages, you MUST do
import a.b.cand notfrom a.b import c
Compatibility with Python
3.10+ is required. Some features break when on 3.9
Development
pixi install
pixi shell --change-ps1=false -e dev
Oh yeah, this project uses pipelight btw because I said so. It is used for pre-commit / push hooks while still being readable and maintainable. You need to download that and Deno then you are good to go. Don't get scared of the deno stuff, this is just for a few things under the hood for logs in dev not prod. 🔥
Publishing releases
In order to do this, I have standardized it via running this command:
scripts/update-version.sh
Metadata
Release files for pybashify 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pybashify-0.1.1.tar.gz | 45.0 kB | Without provenance | Details for pybashify-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pybashify-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for pybashify-0.1.1-py3-none-any.whl |
Total release size: 62.4 kB
Release files / pybashify-0.1.1.tar.gz
| Download URL | pybashify-0.1.1.tar.gz |
|---|---|
| Size | 45.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1592ef5b158e192db0c3bad16c845b881ca234862269cda15f8710a96cf6a8dd
|
|
BLAKE2b-256 checksum How to use checksums |
c3bbf53b0d88b8b5928595144efbeba6ee7f33645ab067290252c8692159fffe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.7
|
Release files / pybashify-0.1.1-py3-none-any.whl
| Download URL | pybashify-0.1.1-py3-none-any.whl |
|---|---|
| Size | 17.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fe53a8fe2e8e5eaf5f9dfa65d4f3038144f6af77b0e38257e90d70842118b046
|
|
BLAKE2b-256 checksum How to use checksums |
baf24b55c574f4b6fea82e9f0b92cb3455c1cf3e82252d7417725eb1ddb5dfb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.7
|
Security for pybashify 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.