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

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).

  • 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

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.

  • 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

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

  • 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

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"
  • 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.