{"id":19293511,"url":"https://github.com/voschezang/mash","last_synced_at":"2025-10-04T18:43:37.549Z","repository":{"id":63914581,"uuid":"571716243","full_name":"voschezang/mash","owner":"voschezang","description":"A Python-based shell and various utilities","archived":false,"fork":false,"pushed_at":"2025-08-12T07:58:47.000Z","size":1731,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-06T09:59:40.731Z","etag":null,"topics":["ast","python","python3","scripting","shell","subshell","yacc","yacc-lex"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voschezang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"zenodo":null}},"created_at":"2022-11-28T18:29:02.000Z","updated_at":"2025-07-17T08:57:06.000Z","dependencies_parsed_at":"2023-12-31T10:22:43.928Z","dependency_job_id":"51689e1f-374c-4e5d-9e22-ec42cf5a9105","html_url":"https://github.com/voschezang/mash","commit_stats":{"total_commits":550,"total_committers":2,"mean_commits":275.0,"dds":0.26,"last_synced_commit":"5bfb8c39a58e6455bf1a07748bd552ea87d231a0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/voschezang/mash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voschezang%2Fmash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voschezang%2Fmash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voschezang%2Fmash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voschezang%2Fmash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voschezang","download_url":"https://codeload.github.com/voschezang/mash/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voschezang%2Fmash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278358488,"owners_count":25973946,"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","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ast","python","python3","scripting","shell","subshell","yacc","yacc-lex"],"created_at":"2024-11-09T22:35:15.694Z","updated_at":"2025-10-04T18:43:37.526Z","avatar_url":"https://github.com/voschezang.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![workflow-badge](https://github.com/voschezang/mash/actions/workflows/python-app.yml/badge.svg)\n\u003ca href=\"https://pypi.org/project/mash-shell\" title=\"Python versions\"\u003e\u003cimg src=\"https://img.shields.io/badge/python-3.13%20|%203.11|%203.9-blue\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/mash-shell\" title=\"PyPI\"\u003e\u003cimg src=\"https://img.shields.io/badge/pypi-v0.2.0-blue\"/\u003e\u003c/a\u003e\n\n**Docs**:\n[Github](https://github.com/voschezang/mash/blob/main/README.md)\n| [Library Docs](https://voschezang.github.io/mash-docs/)\n\n**Markdown docs**:\n| [Shell](https://github.com/voschezang/mash/blob/main/docs/source/pages/shell.md)\n| [Language Reference](https://github.com/voschezang/mash/blob/main/docs/source/pages/language_reference.md)\n| [Using Directories](https://github.com/voschezang/mash/blob/main/docs/source/pages/directories.md)\n\n\u003cimg src=\"https://github.com/voschezang/mash/blob/main/img/dall-E/bosh-terminal-icon.png?raw=true\" style=\"height: 12em\" alt=\"A drawing of a terminal\"\u003e\u003c/img\u003e\n\n# Mash | My Automation Shell\n\nA *shell* that can be used to for automation and (REST) resource discovery. It can be used as a [cli](https://en.wikipedia.org/wiki/Command-line_interface) or [repl](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop). It exposes a [complete](https://en.wikipedia.org/wiki/Turing_completeness) programming [language](https://github.com/voschezang/mash/blob/main/docs/source/pages/language_reference.md) with variables, functions, conditions and pipes. The language can be tailored towards [domain-specific](https://en.wikipedia.org/wiki/Domain-specific_language) applications and it has interoperability with Bash. In addition, this repository contains a library of  utilities.\n\nFeatures:\n\n- A **DSL** that can interpret user-defined commands: `shell.py`.\n- A **file-browser**. Query both static datastructures and REST APIs: `examples/filesystem.py`,\n- A **REST client** to browse APIs with a programmatic yet intuitive interface: `examples/discoverable_api.py`.\n- An **object parser** which converts JSON data to Python classes: `object_parser.py`.\n- An **OAS-generator** for Python classes: `oas.py`.\n- A subshell wrapper, to redirect the output of shell scripts: `subshell.py`.\n- A parallelization framework for load testing: `parallel.py`.\n\nLinks\n\n- [Mash language reference](https://github.com/voschezang/mash/blob/main/docs/source/pages/language_reference.md)\n- [PyPI](https://pypi.org/project/mash-shell)\n- [github](https://github.com/voschezang/mash)\n- [docs](https://voschezang.github.io/mash-docs/)\n\n## Shell\n\n\u003cimg src=\"https://github.com/voschezang/mash/blob/main/img/shell_dropdown.png?raw=true\" style=\"max-height: 180px;\" alt=\"Example of a shell with a dropdown completion menu\"\u003e\u003c/img\u003e\n\n```sh\npip install mash-shell\npython -m mash\n```\n\nSee [`src/examples`](src/examples) for advances usage examples.\n\n**Documentation**\n\n| Implementation: [Shell](https://voschezang.github.io/mash-docs/pages/shell.html)\n\n- Language: [Reference](https://github.com/voschezang/mash/blob/main/SHELL_REFERENCE.md).\n\n**Table of Contents**\n\n- [Usage](#usage)\n  - [CLI](#cli)\n  - [Filesystem (CRUD Operations)](#Filesystem%20(CRUD%20Operations))\n  - [Usage Examples](#Usage%20Examples)\n- [Library \u0026 Tools](#Library%20\u0026%20Tools)\n  - [Parallelization Utilities](#Parallelization%20Utilities)\n  - [Object Parser](#Object%20Parser)\n\n## Usage\n\nSee [reference](SHELL_REFERENCE.md).\n\n### CLI\n\n```sh\n▶ python -m mash -h\nusage: shell.py [-hvsr][-f FILE] [--session SESSION] [cmd [cmd ...]]\n\nIf no positional arguments are given then an interactive subshell is started.\n\npositional arguments:\n  cmd                   A comma- or newline-separated list of commands\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -v, --verbose\n  -s, --safe            Safe-mode. Ask for confirmation before executing commands.\n  -f FILE, --file FILE  Read and run FILE as a commands\n  -r, --reload          Reload last session\n  --session SESSION     Use session SESSION\n```\n\n## Filesystem (CRUD Operations)\n\nSee `examples/filesystem.py` and `examples/discoverable.py`.\n\n| Example             | Description                                                  |\n| ------------------- | ------------------------------------------------------------ |\n| `cd [DIR]`          | Change the current working directory. Alias: `use`           |\n| `list [DIR]`        | List the items in a directory. Use the current working directory by default. Alias: `l` |\n| `foreach [DIR]`     | Iterate over a directory structure. E.g. a resource `users/{id}/email`. |\n| `get NAME`          | Retrieve a file.                                             |\n| `set NAME VALUE`    | Modify a file.                                               |\n| `new NAME [NAME..]` | Create new directories.                                      |\n| `show [NAME]`       | Display detailed information about a directory.              |\n| `cp`, `mv`, `rm`    | Modify files. I.e. copy, move, rename or remove files.       |\n\n## Usage Examples\n\nFor real-world examples, see [lib](https://github.com/voschezang/mash/blob/main/src/lib/math.sh).\n\n### Example 1\n\nSee `src/examples/shell_example.py`. It shows how to use a user-definnable mapping of custom functions.\nIt uses the library `quo` to create a user-friendly subshell with autocompletion prompts.\n\n```sh\n# python3 src/examples/shell_example.py echo 'hello world'\nhello world\n```\n\n### Example 2: REST Client\n\nBrowse through a REST API as if it is mounted as a filesystem.\n\n```sh\n# python3 src/examples/rest_client_implicit.py\n\n$ cd users # browse some.api.com/v1/users\n$ get 2\n|       | values             |\n|:------|:-------------------|\n| email | name.2@company.com |\n| name  | name_2             |\n\n$ flatten 1 2 \u003e\u003e= get users $ email\nname.1@company.com\nname.2@company.com\n\n$ cd -\n$ tree\n{ 'document': 'https://dummy-api.com/v1',\n  'users': { 0: {'email': 'name.0@company.com', 'name': 'name_0'},\n             1: {'email': 'name.1@company.com', 'name': 'name_1'},\n             2: {'email': 'name.2@company.com', 'name': 'name_2'},\n...\n```\n\n### Example 3: Commands\n\nRun commands from a file with `python src/shell -f FILE` or `python -m src.shell -f FILE`.\n\n```sh\n# write to file\nprint A sentence. \u003e out.txt \n!cat out.txt |\u003e export x # save text from file\nprint $x\n\ny \u003c- shell expr 2 + 2 # store result in variable $y\nprint \"result:\" $y # prints \"result: 4\n\nshell expr 2 + 2 -\u003e z # store result in variable $z\nprint \"result:\" $z # prints \"result: 4\n```\n\n### Example 4: File System Simulation\n\nSupport both static and dynamic data.\n\n#### With Static Data\n\nSee `src/examples/filesystem_example.py`. This simulates a REST resources with a directory hierarchy.\nIn addition, it provides fuzzy name completion.\n\n```sh\n$ python src/examples/shell_example.py tree\n# example data with dicts and lists\nrepository = {'worlds': [\n    {'name': 'earth',\n     'animals': [\n         {'name': 'terrestrial',\n          'snakes': [{'name': 'python'},\n                     {'name': 'cobra'}]},\n         {'name': 'aquatic',\n          'penquins': [{'name': 'tux'}]}\n     ]}]}\n```\n\n```sh\n# note the autocompletion\n$ python src/examples/filesystem.py 'cd world; cd a; cd t; cd snakes; ll'\npython\ncobra\n```\n\n#### With Dynamic Data\n\nSee `examples/discoverable.py`.\n\n```sh\n# list remote/auto-generated data\n$ python src/examples/discoverable.py 'ls'\ndepartment_805, department_399\n\n# refresh data, then save\n$ py src/examples/discoverable.py 'ls ; save'\ndepartment_750, department_14\n\n# reload data\n$ python src/examples/discoverable.py 'ls'\ndepartment_750, department_14\n```\n\n## Library \u0026 Tools\n\nRepository structure\n\n```sh\nsrc\n├── examples\n├── lib # mash shell scripts\n└── mash\n    ├── filesystem # Directory-based datastructures: FileSystem, View\n    ├── object_parser # Parse JSON objects\n    └── shell # Shell, ShellWithFileSystem\ntest\n```\n\n## Setup\n\nUsing a `Makefile` for convenience.\n\n```sh\nmake install\nmake test\n```\n\n## Parallelization Utilities\n\nSome experiments with parallelization, concurrency and `asyncio` in Python.\n\n### Test\n\nStart a dummy server.\n\n```sh\npython3 src/server.py\n```\n\nDo a simple load test\n\n```sh\npython3 src/parallel.py -v\n```\n\n## Object Parser\n\n- [src/mash/object_parser/object_parser.py](object_parser.py) parses JSON data and instantiate Python objects.\n- [src/mash/object_parser/oas.py](oas.py) converts domain-models to OAS.\n\n### Example\n\n```sh\npython src/examples/object_parser.py\n```\n\n\u003cimg src=\"https://github.com/voschezang/data-science-templates/blob/main/img/generated_oas.png?raw=true\" style=\"width: 400px\" alt=\"OAS Example\"\u003e\n\n### REST API\n\nServer\n\n```sh\npython src/mash/object_parser/object_parser.py\n```\n\nClient\n\n```sh\ncurl -X 'POST' 'http://localhost:5000/v1/organizations' \\\n  -H 'Content-Type: application/json' \\\n  -d '{ \"board\": [ \"string\" ], \"ceo\": \"string\", \"departments\": [ { \"manager\": \"string\", \"teams\": [ { \"manager\": \"string\", \"members\": [ \"string\" ], \"team_type\": \"A\", \"active\": true, \"capacity\": 0, \"value\": 0 } ] } ] }'\n```\n\n# Release History\n\n- July 2023: Implemented auto-generated [documentation](https://github.com/voschezang/mash/commit/39e6b1d00b0a3f0a050b2868ba05530bd7f7852a) at [voschezang.github.io/mash-docs/](https://voschezang.github.io/mash-docs/)\n- March 2023: [Rewrote](https://github.com/voschezang/mash/commit/eef85a7d8ed13e378695953070a9e4383da92fbf) shell to use a lexer (AST)\n- August 2022: Created [filesystem simulation](\u003chttps://github.com/voschezang/mash/commit/ed8860ff505eeaf2aa48412dcaef777705896655\u003e)\n- July 2022: First [DSL module](https://github.com/voschezang/mash/commit/c95cf57e06b1a21e4ae01ae00a11a19996e91ef0) with examples.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoschezang%2Fmash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoschezang%2Fmash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoschezang%2Fmash/lists"}