{"id":39689477,"url":"https://github.com/mulle-sde/mulle-env","last_synced_at":"2026-01-18T10:04:05.284Z","repository":{"id":139651392,"uuid":"116177458","full_name":"mulle-sde/mulle-env","owner":"mulle-sde","description":"🌳 Virtual environment for Unix ","archived":false,"fork":false,"pushed_at":"2026-01-17T18:22:08.000Z","size":758,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-18T04:42:40.704Z","etag":null,"topics":["bash","command-line-tool","env","environment","environment-variables","shell","virtualenv"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mulle-sde.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-01-03T20:10:23.000Z","updated_at":"2026-01-17T18:22:09.000Z","dependencies_parsed_at":"2024-03-02T17:29:30.489Z","dependency_job_id":"bb0b3e0c-12c9-4533-8fb1-468957611ac5","html_url":"https://github.com/mulle-sde/mulle-env","commit_stats":null,"previous_names":[],"tags_count":150,"template":false,"template_full_name":null,"purl":"pkg:github/mulle-sde/mulle-env","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-env","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-env/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-env/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-env/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mulle-sde","download_url":"https://codeload.github.com/mulle-sde/mulle-env/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-env/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28534210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"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":["bash","command-line-tool","env","environment","environment-variables","shell","virtualenv"],"created_at":"2026-01-18T10:04:05.220Z","updated_at":"2026-01-18T10:04:05.271Z","avatar_url":"https://github.com/mulle-sde.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌳 Virtual environment for C and Objective-C\n\n... for Android, BSDs, Linux, macOS, SunOS, Windows (MinGW, WSL)\n\n**mulle-env** provides a virtual environment as an interactive bash shell.\nDeveloping inside the virtual environment protects you from the following\ncommon mistakes:\n\n* inadvertant reliance on non-standard tools\n* reproducability problems due to personal or non-standard environment variables\n\nWith **mulle-env** you can easily manage\n\n* the command line tools available in the virtual environment\n* additional environment variables with multiple scopes, like on a per-user or per-host basis.\n\nYou can turn any directory into a self contained virtual environment.\n`mulle-env init` will create a `.mulle` folder to hold all permanent and\ntemporary data. Remove that folder and the virtual environment is gone.\n\nAnother benefit of the virtual environment is a per-project command shell\nhistory.\n\n\n\n\n\n\n| Release Version                                       | Release Notes\n|-------------------------------------------------------|--------------\n| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-sde/mulle-env.svg)  | [RELEASENOTES](RELEASENOTES.md) |\n\n| Executable          | Description\n|---------------------|--------------------------------\n| `mulle-env`         | Virtual environment sub-shell\n| `mudo`              | Run a command with the unrestricted PATH/environment\n| `mulle-env-reload`  | Refresh virtual environment variables\n\n\n\n\n\n\n## Init a directory to use mulle-env\n\nA directory must be initialized, before you can run the **mulle-env** subshell\nit it. Let's try an example with a `project` directory. We want a minimal\nportable set of commandline tools, so we specify the 'style' as \"minimal/tight\".\n\n``` sh\nmulle-env init -d project --style minimal/tight\n```\n\nAnd this is what happens:\n\n![Filesystem overview](dox/mulle-env-overview.svg)\n\nTemporary and host-specific data is kept in `var`. User edits in `etc`.\n`mulle-env` installs its content in `share` (and write protects it).\n\n``` sh\n$ mulle-env project\nEnter the environment:\n   mulle-env \"project\"\n$ mulle-env \"project\"\n$ ls\n$ echo $PATH\n/tmp/project/.mulle/var/\u003chostname\u003e-\u003cusername\u003e/env/bin\n$ ls -l $PATH\ntotal 0\nlrwxrwxrwx 1 nat nat 12 Jan 21 22:28 awk -\u003e /usr/bin/awk\nlrwxrwxrwx 1 nat nat 15 Jan 21 22:28 base64 -\u003e /usr/bin/base64\n...\n...\n...\nlrwxrwxrwx 1 nat nat 14 Jan 21 22:28 which -\u003e /usr/bin/which\n```\n\nAnd we leave the subshell with\n\n``` sh\n$ exit\n```\n\nYou can also run a command in the environment without an interactive subshell\nwith the '-c' flag, like you would using bash:\n\n\n``` sh\n$ mulle-env -c 'printf \"%s\\n\" \"${PATH}\"'\n```\n\n\n## Environment\n\n### In an out\n\nEnter the subshell with `mulle-env` and leave the subshell `exit`.\nRun any command in the subshell (from the outside to the inside) with a\ncommand like `mulle-env -c env` and escape the subshell (from the inside to\nthe outside) with `mudo -e env`.\n\n## Upgrade an environment\n\nTo upgrade an environment to a newer mulle-env release use\n\n``` sh\nmulle-env upgrade\n```\n\n\n### Manage variables\n\nList all environment variables defined by the virtual environment\nwith `mulle-env environment list`. Set an environment variable\nwith `mulle-env environment --scope global set FOO \"whatever\"`.\n\nYou can also get an environment variable with `mulle-env environment get FOO`\nand remove it with `mulle-env environment remove FOO`.\n\n#### Scopes\n\nThere are multiple environment variable scopes, that override each other\nin top (weakest) to bottom (strongest) fashion. Non-user values will lose\nchanges on mulle-env upgrades, so don't write into those scopes.\n\n\n| Scope         | User Value | Description\n|---------------|------------|----------------------------------\n| `plugin`      | NO         | Values set by a mulle-env plugin\n| `global`      | YES        | Global user values\n| `os-\u003cname\u003e`   | YES        | Operating system specific user values\n| `host-\u003cname\u003e` | YES        | Host specific user values\n| `user-\u003cname\u003e` | YES        | User specific user values\n\n### Manage tools\n\nTools are your standard unix tools, executables like `cc`, `ls` or `make`.\nWith the PATH restrictions enforced my mulle-env, you can prune the number\nof available tools to the subshell.\n\nTo list all tools use `mulle-env tool list`. You can add a tool with\n`mulle-env tool add git` and remove it with `mulle-env tool remove git`.\n\n### Styles\n\nA style is mix of a tool-style and an env-style of the form\n`\u003ctool\u003e/\u003cenv\u003e`. The env-style determines the filtering of the environment\nvariables. The tool-style influences the content of the `PATH` variable.\n\n\u003e Toolstyles can be augmented with plugins. See `mulle-env toolstyles` for\n\u003e what's available.\n\n| Tool Style  | Descripton\n|-------------|--------------------------\n| `none`      | No default commands available.\n| `minimal`   | PATH with a minimal `/bin` like set of tools like `ls` or `chmod`\n| `developer` | PATH with a a set of common unix tools like `awk` or `man` in addition to `minimal`\n| `mulle`     | *if mulle-sde is installed this tool style is also available*\n\n\n| Environment Style | Description\n|-------------------|--------------------------\n| `tight`           | All environment variables must be defined via `mulle-env` (academic needs only)\n| `restrict`        | Inherit some environment environment variables (e.g. SSH_TTY)\n| `relax`           | Like `restrict` plus `PATH` adds all `/bin` and `/usr/bin` tools\n| `inherit`         | The environment is restricted but tool style is ignored and the original PATH is unchanged.\n| `wild`            | The user environment remains unchanged and the tool style is ignored.\n\n\n\n\n## What mulle-env does in a nutshell\n\nmulle-env uses `env` to restrict the environment of the subshell to a minimal\nset of values. With `env -i bash -c env` you can see the restricted environment\n\n``` bash\nPWD=/home/src/srcS/mulle-env\nSHLVL=1\n_=/usr/bin/env\n```\n\nmulle-env adds a few environment variables back to the environment, like\n`LOGNAME` or `SSH_AUTH_SOCK`, so that an interactive shell keeps functioning\nlike one would expect it to. You can see the effect for yourself with:\n\n``` bash\nmulle-env invoke env  # this does not read a custom environment\n```\n\n### Custom environment\n\nWhen a mulle-env subshell executes, the environment is modified by reading a \nprofile file `.mulle/share/env/environment.sh`. This file in turn will read \nother files in `.mulle/share/env` and `.mulle/etc/env`. With these files \nyou define new environment variables and aliases. \n\nUsually you do not manually edit this files, but use mulle-env *commands*\nto customize these environment files.\n\nIf you want to go manual, it's suggested you use `.mulle/etc/env/environment-global.sh`\nas a starting point:\n\nExample:\n\n``` bash\nmkdir -p .mulle/etc/env\necho \"FOO=xxx\" \u003e .mulle/etc/env/environment-global.sh\n```\n\n\n\n## Environment\n\n### In an out\n\nEnter the subshell with `mulle-env` and leave the subshell `exit`.\nRun any command in the subshell (from the outside to the inside) with a\ncommand like `mulle-env -c env` and escape the subshell (from the inside to\nthe outside) with `mudo -e env`.\n\n## Upgrade an environment\n\nTo upgrade an environment to a newer mulle-env release use\n\n``` sh\nmulle-env upgrade\n```\n\n\n### Manage variables\n\nList all environment variables defined by the virtual environment\nwith `mulle-env environment list`. Set an environment variable\nwith `mulle-env environment --scope global set FOO \"whatever\"`.\n\nYou can also get an environment variable with `mulle-env environment get FOO`\nand remove it with `mulle-env environment remove FOO`.\n\n#### Scopes\n\nThere are multiple environment variable scopes, that override each other\nin top (weakest) to bottom (strongest) fashion. Non-user values will lose\nchanges on mulle-env upgrades, so don't write into those scopes.\n\n\n| Scope         | User Value | Description\n|---------------|------------|----------------------------------\n| `plugin`      | NO         | Values set by a mulle-env plugin\n| `global`      | YES        | Global user values\n| `os-\u003cname\u003e`   | YES        | Operating system specific user values\n| `host-\u003cname\u003e` | YES        | Host specific user values\n| `user-\u003cname\u003e` | YES        | User specific user values\n\n\n\n\n\n## Install\n\nSee [mulle-sde-developer](//github.com/mulle-sde/mulle-sde-developer) how to\ninstall mulle-sde, which will also install mulle-env with required\ndependencies.\n\nThe command to install only the latest mulle-env into\n`/usr/local` (with **sudo**) is:\n\n``` bash\ncurl -L 'https://github.com/mulle-sde/mulle-env/archive/latest.tar.gz' \\\n | tar xfz - \u0026\u0026 cd 'mulle-env-latest' \u0026\u0026 sudo ./bin/installer /usr/local\n```\n\n\n\n## Author\n\n[Nat!](https://mulle-kybernetik.com/weblog) for Mulle kybernetiK\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-env","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmulle-sde%2Fmulle-env","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-env/lists"}