I want to use different aliases (or perhaps: the same alias differently) depending on the current working directory. For example, I might want to use l as a shorthand for ls with some extra options. I want to use two variants:

alias l="ls --sort=extension" # variant A
alias l="ls --quoting-style=literal" # variant B

Normally, I would like to use variant A. However, I want to use variant B when listing pictures – that is, when my working directory is ~/pictures. (This is merely a minimal example. My actual use case is more complicated.)

I am aware that I could simply write a function l() with a case differentiation on the output of $(pwd). However, I want a more robust solution which allows me to rename the specific directories without changing any alias (and that doesn’t clutter my .zshrc).

But is it possible to overwrite or add aliases, e.g. by setting up a local .zshrc within the relevant directory (like it is possible for vim and a local .vimrc)?

Furthermore, is it (also) possible in bash or any other shell?

  • I'm sure zsh has similiar functionality, but another route could be to hook into 'cd' (or prompt_command) and run a function that overwrites aliases as needed. – Jeff Schaller Jul 5 '17 at 15:55

If you are using oh my zsh, just activate the dotenv plugin:


Also consider direnv, which lets you export environment variables in a per-directory .envrc, and unset them when you move away (which dotenv cannot do). direnv is compatible with all the popular shells. However, it doesn't currently let you define aliases or functions.

You can still combine ilkkachu's approach with direnv, by creating a function (rather than an alias) that decides what to do based on one (or several) environment variables, which are in turn set by direnv.

Both approaches deal with the security aspect by having you manually whitelist directories in which the dot files will be sourced.

| improve this answer | |
  • 1
    sounds even worse from a security standpoint than Microsoft's infamous AUTORUN. – Stéphane Chazelas Jun 10 at 9:45
  • @StéphaneChazelas Can you elaborate or provide a reference? – k.stm Jun 27 at 21:38
  • @k.stm, I mean running arbitrary code stored in any of the directories you traverse could be abused the same way autoruns were abused to spread malware on Microsoft systems. I can see now that dotenv seems to allow some form of whitelisting which would mitigate the risk somewhat, but that's still risky, in that if one day you allow /media/cdrom or /tmp/something for instance, you leave a door open for abuse in the future. – Stéphane Chazelas Jun 28 at 6:55
  • @StéphaneChazelas Yes, thanks for the explanation! I don’t think the hazard is too great though when using whitelisting. – k.stm Jun 28 at 15:23

You could create a function or a script to check some file in the current directory and change behaviour based on that:

l() {
    if [ -f ./.ls-literal-quote ] ; then
         ls --quoting-style=literal "$@"
         ls --sort=extension "$@"

Something like that would allow you to keep the configuration in the directory itself, instead of some centralized location if that's what you want.

Now, that requires littering the involved directories with extra files, but you might be able to work around that by using extended attributes (if your system supports that).

| improve this answer | |
  • Yes, that would work. But with a lot of such local deviations of aliases, that method would quickly clutter my .zshrc and become less manageable. Anyway, that would work. (Thanks!) – k.stm Jul 5 '17 at 15:57

I'm working on a project that accomplishes just that. Check it out: localalias.

It allows you to create and use pseudo-aliases and functions that are local to the directory they are defined in. Perhaps the best part is that it accomplishes this without performing any dicey "source" commands. These solutions are easier and faster, but are a big security concern.

Here's a demo:

enter image description here

| improve this answer | |
  • When evaluating an otherwise invalid command, are global aliases checked before local aliases? It would be nice to have local aliases take priority. (And maybe even before valid commands themselves, but this may be risky I guess …) – k.stm Jan 6 '18 at 15:07
  • 1
    You could make it work that way by redefining chpwd as mentioned in this article. Add a conditional check for $(pwd)/.lshrc. If found, source it. Otherwise, source zshrc. This is less secure. My real problem with this method, however, is that it pollutes the namespace, making it hard to know which aliases are defined at any given moment. You can use unalias -a at the top of your zshrc to reduce this pollution, but I don't think there is an equivalent command for function definitions. – Bryan Bugyi Jan 7 '18 at 3:37

If you want a clean alias that is robust, complex, and extensible, the first option that comes to mind is creating a bona-fide script (e. g. l) that you keep in ~/bin. You could then either add this directory to your PATH or create an alias which explicitly calls it for you.

| improve this answer | |
  • I don’t quite get this: What would be the contents of such a script – the same as that of zsh function l() in .zshrc solving the problem? If I was to rename the relevant directory, e.g. $ mv ~/pictures ~/videos, would I have to adapt the script you are talking about? – k.stm Jul 5 '17 at 15:48
  • Yes, you would have to keep the script up to date for your use-case, but maintaining such a script is more tenable than maintaining an alias. You could changes ls's behavior in a simple case $(pwd | sed 's_^.*/__') stanza. – DopeGhoti Jul 5 '17 at 16:17

Sure; just make the alias expand to some shell code that does the test for you:

alias l="[[ $PWD =~ /pictures$ ]] && ls --quoting-style=literal || ls --sort=extension"
| improve this answer | |
  • Then I would still have to change the alias when renaming ~/pictures to ~/videos. – k.stm Jul 5 '17 at 15:51
  • extend the [[ to be a case statement, if you have other variations you want to use – Jeff Schaller Jul 5 '17 at 15:51
  • how would the alias know what to do if you rename a folder? I think you'd have to tell it ahead of time. – Jeff Schaller Jul 5 '17 at 15:51
  • As I said, I want to add or overwrite existing aliases depending on the current working directory. So this would have to take advantage of some (maybe nonexisting) feature of zsh interpreting aliases differently depending on some context. – k.stm Jul 5 '17 at 15:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.