aliases: bash aliases that change with the directory you are in
Contextual, dynamic aliases for the bash shell
At a glance
- What is it?
- The aliases tool is a Rust program that reads a .aliases YAML file in each project directory and makes those commands available as bash aliases in that directory only, with a rehash step, global and per-user alias layers, optional confirmation prompts and backout windows. It suits developers who keep typing the same handful of project commands, and the trade is that the tool installs shims and a shell hook into your environment, and that its own list of known bugs includes one where a malformed alias file is silently treated as empty.
- Who is it for?
- Adopt aliases if you work in several repositories that each have their own project commands and you want those commands available without remembering which script lives where. Do not adopt it if you only have one or two aliases, since a shell function does the same job, and check the known bugs list before you rely on it, because a malformed .aliases file is currently accepted silently rather than reported.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 35 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Aliases scoped to a directory, defined in YAML
aliases is a tool for contextual, dynamic aliases for the bash shell, and the opening example is the clearest statement of the idea. You want to type something like `server` in a whole bunch of different directories and have the computer just know what you are thinking.
The design starts from a limitation of the shell's own mechanism. Bash aliases are cool but limited, they are globals and have limited configurability. The specific downside the project names is that they do not take arguments, and the common workaround is to write shell functions:
function ll {
ls -la "$@"
}The downside of that function is that it is hard to tell where it came from, you cannot just type `which ll` and find the function. You also end up writing a whole lot of functions that are really similar, plus none of these are dynamic or contextual.
So the tool's answer is to make the alias definition a file that lives next to the code it is for. Run `aliases init` in a directory and it creates a `.aliases` file in the current directory with a commented out alias structure:
# alias_name:
# command: ./super_command.sh # required
# confirm: true # optional - You will be asked to confirm before execution
# confirmation_message: Are you sure you are sure?? # optional - If confirm is set to true then you this is your confirmation message
# conditional: /bin/true # optional - A bash command that needs to be successful for the alias to run
# backout_seconds: 3 # optional - Give's you a backout option (ctrl + c) before the alias is executed
# unit_test: '[ true = true ]' # optional - A bash command that tells whether the alias is doing what you want
# quiet: false # optional - default 'false', when set to false evaluated command is printed to stderr before runningEvery option after `command` is optional, and the file is meant to be edited and then reloaded with `aliases rehash` to make the alias available.
The key property is that the file is per directory. An alias defined in one repository is not available in another, which is the whole point, and the file is meant to be checked in to the repo so that everyone working on it gets the same commands.
Confirmations, conditionals and the backout window
The optional fields are where the tool stops being a wrapper and starts being a policy layer, and they are worth understanding individually.
`confirm: true` means you are asked to confirm before execution, with `confirmation_message` supplying the text of that prompt. That is for the destructive command, the deploy to production, where a single keystroke is the difference between a good afternoon and a bad one.
`conditional` is a bash command that needs to be successful for the alias to run. The example in the README uses it to gate a production deploy on the current git branch:
l:
command: ls
gc:
command: git commit
deploy_production:
command: bundle exec cap production deploy
backout_seconds: 3
conditional: test git rev-parse --abbrev-ref HEAD` == "master"
deploy_staging:
command: bundle exec cap staging deploySo the production deploy only runs when you are on master, and the staging deploy has no gate. That is a guard rail implemented in a file that lives next to the project, which is a better place for it than a shell function in a dotfile, because the person who writes the deploy is the person who writes the rule.
`backout_seconds` gives you a window in which to press Ctrl+C before the alias executes, three seconds in the example. It is the same idea as the confirmation prompt but faster and quieter, for the case where you are already sure you meant to run it and just want a moment to change your mind.
`unit_test` is a bash command that tells whether the alias is doing what you want, and `quiet` defaults to false, so when set to false the evaluated command is printed to stderr before running. The printing is a deliberate choice: a command you did not write should announce itself before it runs, and stderr rather than stdout keeps it out of a pipeline.
Taken together these fields turn the tool from a shortcut manager into something closer to a guarded entry point, and they are the reason a project might adopt it rather than writing three functions in a dotfile.
Global aliases, user aliases and the rehash model
The tool has layers, and the precedence rules are where the real behaviour lives.
Global aliases are created by running `aliases init` in your home directory, and they are overridden by local aliases if they exist. So a global `deploy` can exist and a project's own `deploy` wins in that project, which is the sensible default for a tool whose whole premise is that the project directory decides.
User aliases are a third layer, for people who work with several sets of commands. `aliases init --user superman` creates a new empty `.aliases-superman` file in the current directory and adds the user `superman` to the list of alias users. If the repo already has a `.aliases-superman` the file is left untouched and the user is added to the list.
The next time you run `aliases rehash`, all the superman aliases in all initialised directories are updated. User aliases are merged together to create the list of available aliases, and if there are clashing aliases the alias user prioritised highest wins.
You can see all the users and their prioritisation with `aliases users`, and the current prioritisation order is in the config file:
cat ~/.aliases_cfgThere is also an environment variable for a temporary override:
export ALIASES_USER=supermanwhich the README frames as useful when you are pairing and sharing your shell.
The rehash model is the one operational detail to understand. Aliases are not live. You edit a file, you run `aliases rehash`, and the change takes effect. The same applies when the directory changes, since the list of aliases is a function of which directories contain alias files, and rehash is what recomputes it. `aliases` on its own lists everything currently available.
The tool also syncs user aliases with GitHub:
aliases clone sebglazebrook # this could pull from github.com/sebglazebrook/.aliases repo
aliases clone sebglazebrook https://some-other-address # pulls from the given repo
aliases pull sebglazberook # pull and show the diffso a person can publish their alias set and a colleague can pull it.
Installing on macOS and Linux, and the shell hook
Installation is short, and there is a Linux path that requires you to be a bit more deliberate.
On macOS, Homebrew:
brew install sebglazebrook/aliases/aliasesOn Linux, the README says there are some debian packages in the released directory, so you can clone the repo and do something like this:
apt install ./releases/0.8.1/debian/aliases_0.8.1.deband that you will need to sudo that, of course.
Then the step that makes the tool work, which is adding the aliases initialisation config to your .bashrc or any file that is loaded when your user logs in:
aliases init --global >> ~/.bashrcThat last command is the integration point. The tool installs a shell hook into your login file, and the hook is what makes the aliases appear in the current directory. It is also the part worth understanding before you run it, because it is writing to a file that bash reads on every new shell, and the tool's own list of possible future features includes a clean uninstall, removing shims etc, which suggests the removal story is not complete today.
Compiling from source is listed as TODO in the README, so the source route is not documented. The development environment is a Docker setup instead. The Dockerfile is a single line, `FROM sebglazebrook/rust-nightly:latest`, and the compose file has a `data` service running that image with the cargo directory and the bash history mounted, and a `rust` service built from the repository with the code mounted and a bash command, sharing the data service's volumes. The project says it uses docker containers so the team can share the same development environment.
The Cargo manifest shows the dependencies, and they are the usual Rust CLI set: yaml-rust for the YAML parsing, regex, rust-crypto, rustc-serialize, tabwriter for the list output, countdown for the backout window, crossbeam, log and env_logger, scoped-pool for the thread pool the project notes it should be using more carefully, and clap 2.16.4 with its yaml feature for the command line. The tests are RSpec, with a `.rspec` file and a `spec/` directory, and the dev dependency gag is the crate used to capture output in tests.
The known bugs section, which is unusually candid
The README has a section titled Bugs to fix, and for a project of this size it is worth reading in full rather than skipping, because it tells you what the tool does when things go wrong.
The listed items are: handle different process signals, check the user's config is out of whack, such as missing a key, because it blows up, and when listing, alert the user if the directory has not been initialised.
The fourth item is the one to think about. `AliasFactory::create_from_file` never actually rejects malformed `.aliases` content as invalid, and a test for this exists but is `#[ignore]`d, with the note that it is to be decided whether malformed files should error or continue being silently treated as empty.
So the current behaviour is that a broken alias file is treated as an empty one. The test that would catch it is written and disabled, which means the behaviour is known and deliberate for now, and the decision is open. In practice this means a typo in a `.aliases` file is not reported as a syntax error. You get no aliases from that file, and since the file is checked in, the breakage is shared with everyone else on the project, which is a real operational cost of the design.
The small improvements list is also informative about the current state. It includes handling when number arguments are not in order, adding a description of an alias visible in list view, sorting the alias lists better and making it more obvious which ones are local, colours for user interactions, using a thread pool when running the rehash command to avoid too many threads, and adding more data about the aliases and user in the list view. The thread pool item connects back to the `scoped-pool` dependency, which suggests the rehash command currently spawns more threads than it should for a large directory tree.
The last section lists a possible future feature that is really a limitation stated plainly: all aliases are hardcoded to run inside a bash shell, and the tool could allow a user to set a default shell or override it, so it could be sh or zsh. Combined with the positional arguments feature, which is documented as a feature in development and assumes the position keys are continuous, the current capability set is clear.
Editorial conclusion
Adopt aliases if you work in several repositories that each have their own project commands and you want those commands available without remembering which script lives where. Do not adopt it if you only have one or two aliases, since a shell function does the same job, and check the known bugs list before you rely on it, because a malformed .aliases file is currently accepted silently rather than reported.
Frequently asked questions
What does the aliases tool do?
It provides contextual, dynamic aliases for the bash shell, based on the directory you are currently in. You create a .aliases file in a project with `aliases init`, edit it, and run `aliases rehash` to make those commands available as bash aliases in that directory.
How do I install aliases?
On macOS, `brew install sebglazebrook/aliases/aliases`. On Linux, the README points at debian packages in the released directory, installed with something like `apt install ./releases/0.8.1/debian/aliases_0.8.1.deb`, which needs sudo. Then add the init config to your login file with `aliases init --global >> ~/.bashrc`.
What options can an alias have?
The command is required. The optional ones are confirm with a confirmation_message, conditional as a bash command that must succeed for the alias to run, backout_seconds for a Ctrl+C window before execution, unit_test to check the alias behaves, and quiet, where the evaluated command is printed to stderr before running when set to false.
How do global and user aliases interact?
Global aliases come from running `aliases init` in your home directory and are overridden by local aliases if they exist. User aliases are created with `aliases init --user superman`, which adds the user to the list of alias users, and on the next `aliases rehash` all their aliases in all initialised directories are updated, with clashing aliases resolved in favour of the highest prioritised user.
What happens if an .aliases file is malformed?
Currently it is silently treated as empty rather than rejected. The README lists this as a known bug, noting that AliasFactory::create_from_file never actually rejects malformed content as invalid, that a test for it exists but is ignored, and that it is to be decided whether malformed files should error.
Is the aliases tool still being maintained?
The repository is not archived and the last push was on 2026-09-18, with no GitHub releases. The Cargo manifest is at version 0.8.1 and the project is written in Rust, with the test suite in RSpec and a Docker based development environment.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sebglazebrook-aliases)Was this useful?