Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say I have a project in:

~/working_dir

Whenever I run commands from this directory, I need to have certain environment variables set. So I can export them like so:

export VAR=value

However, there are a lot of these and it gets tedious, plus I forget sometimes and run a command only to have it fail because it's missing the environment variables that give it API keys or something.

Is there a way I can get zsh to remember these environment variables for this directory, so that any time I run any command from that directory it runs with those environment variables set?

share|improve this question

It's possible to do this - here's a screencast, using the Grml ZSH configuration.

Further information:

Edit: This is actually pretty easy to do. Here's the relevant portion of your ~/.zshrc:

function chpwd_profiles() {
    local profile context
    local -i reexecute

    context=":chpwd:profiles:$PWD"
    zstyle -s "$context" profile profile || profile='default'
    zstyle -T "$context" re-execute && reexecute=1 || reexecute=0

    if (( ${+parameters[CHPWD_PROFILE]} == 0 )); then
        typeset -g CHPWD_PROFILE
        local CHPWD_PROFILES_INIT=1
        (( ${+functions[chpwd_profiles_init]} )) && chpwd_profiles_init
    elif [[ $profile != $CHPWD_PROFILE ]]; then
        (( ${+functions[chpwd_leave_profile_$CHPWD_PROFILE]} )) \
            && chpwd_leave_profile_${CHPWD_PROFILE}
    fi  
    if (( reexecute )) || [[ $profile != $CHPWD_PROFILE ]]; then
        (( ${+functions[chpwd_profile_$profile]} )) && chpwd_profile_${profile}
    fi  

    CHPWD_PROFILE="${profile}"
    return 0
}
# Add the chpwd_profiles() function to the list called by chpwd()!
chpwd_functions=( ${chpwd_functions} chpwd_profiles )

Activate the profile for each directory you want:

zstyle ':chpwd:profiles:/path/to/directory(|/|/*)' profile NAME

And don't forget to actually make a profile:

chpwd_profile_NAME() {
    [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1
    print "chpwd(): Switching to profile: $profile"

    export VAR=value
}

Edit #2: This would actually be rather neat to couple with named directories [Stackoverflow.net].

share|improve this answer
1  
There is nothing "easy" about this solution. – rane Feb 27 '15 at 20:01

You can use https://github.com/horosgrisa/autoenv to achieve that. I use antigen to active that like this:

antigen bundle horosgrisa/autoenv

Then when you go into a directory with a .env file in it, it will be sourced and you can ser the variables there.

share|improve this answer

Not per directory, no, but if they are the same you can put them in your startup files (.bash_profile for bash, not sure what it is for zsh). Otherwise, I'd suggest just putting all the settings in a file in that directory and sourcing it before running commands. Not an ideal solution, but I think it's close to the best you'll be able to find.

share|improve this answer

You can create a script that sets up the env and changes you to that directory.. then use it instead of cd working_dir

share|improve this answer

Even though this is an old question, I'd like to add this easy solution from https://coderwall.com/p/a3xreg/per-directory-zsh-config

// Add this to your ~/.zshrc
function chpwd() {
  if [ -r $PWD/.zsh_config ]; then
    source $PWD/.zsh_config
  else
    source $HOME/.zshrc
  fi
}
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .