Is there a nice way to set directory/project local environment variables?












4















I have been working on several projects, and they require different environment variables (e.g., PATH for different versions of clang executables, PYTHONPATH for several external modules). Whenever I work on one project, I have to modify these environment variables myself (e.g., change .zshrc/.bashrc and source it); and I sometimes forget and make mistakes.



Is there a way/project that helps do this automatically, similar to what virtualenv does in Python?










share|improve this question

























  • The Environment Modules package may do what you want.

    – Mark Plotnick
    Mar 24 '15 at 8:44













  • @MarkPlotnick Is there a similar one that is documented and maintained well?

    – Hongxu Chen
    Mar 24 '15 at 9:43
















4















I have been working on several projects, and they require different environment variables (e.g., PATH for different versions of clang executables, PYTHONPATH for several external modules). Whenever I work on one project, I have to modify these environment variables myself (e.g., change .zshrc/.bashrc and source it); and I sometimes forget and make mistakes.



Is there a way/project that helps do this automatically, similar to what virtualenv does in Python?










share|improve this question

























  • The Environment Modules package may do what you want.

    – Mark Plotnick
    Mar 24 '15 at 8:44













  • @MarkPlotnick Is there a similar one that is documented and maintained well?

    – Hongxu Chen
    Mar 24 '15 at 9:43














4












4








4


2






I have been working on several projects, and they require different environment variables (e.g., PATH for different versions of clang executables, PYTHONPATH for several external modules). Whenever I work on one project, I have to modify these environment variables myself (e.g., change .zshrc/.bashrc and source it); and I sometimes forget and make mistakes.



Is there a way/project that helps do this automatically, similar to what virtualenv does in Python?










share|improve this question
















I have been working on several projects, and they require different environment variables (e.g., PATH for different versions of clang executables, PYTHONPATH for several external modules). Whenever I work on one project, I have to modify these environment variables myself (e.g., change .zshrc/.bashrc and source it); and I sometimes forget and make mistakes.



Is there a way/project that helps do this automatically, similar to what virtualenv does in Python?







bash shell zsh environment-variables






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 21 '15 at 12:49









Sildoreth

89831537




89831537










asked Mar 24 '15 at 2:19









Hongxu ChenHongxu Chen

2,08951624




2,08951624













  • The Environment Modules package may do what you want.

    – Mark Plotnick
    Mar 24 '15 at 8:44













  • @MarkPlotnick Is there a similar one that is documented and maintained well?

    – Hongxu Chen
    Mar 24 '15 at 9:43



















  • The Environment Modules package may do what you want.

    – Mark Plotnick
    Mar 24 '15 at 8:44













  • @MarkPlotnick Is there a similar one that is documented and maintained well?

    – Hongxu Chen
    Mar 24 '15 at 9:43

















The Environment Modules package may do what you want.

– Mark Plotnick
Mar 24 '15 at 8:44







The Environment Modules package may do what you want.

– Mark Plotnick
Mar 24 '15 at 8:44















@MarkPlotnick Is there a similar one that is documented and maintained well?

– Hongxu Chen
Mar 24 '15 at 9:43





@MarkPlotnick Is there a similar one that is documented and maintained well?

– Hongxu Chen
Mar 24 '15 at 9:43










5 Answers
5






active

oldest

votes


















0














You can source any file you like, it doesn't have to be .zshrc. You could make an env-setup script for each different project, and keep it in the project directory.



If you want to be able to start new shells and have them load the env settings, you have a couple options:




  • Always start your shells in the project directory, and have your .zshrc [[ -e ./PROJECT-ENV.sh ]] && source ./PROJECT-ENV.sh (which you keep there). DANGEROUS: starting a new shell in a directory with hostile contents runs whatever code is in the file you source.


  • .zshrc: source ~/current-project.sh. update current project with ln -sf "$PWD/THIS-PROJECT-ENV.sh ~/current-project.sh


If only a few commands for each project need the env vars set, you could make wrapper scripts for them that set the variables, and then leave your shell rc file untouched.



Another idea: you could hack something into PROMPT_COMMAND, which runs before every prompt is displayed. Or hook cd/pushd/popd by writing shell functions with those names which check/set env vars and then run builtin cd.






share|improve this answer


























  • Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

    – Hongxu Chen
    Apr 20 '15 at 6:12











  • or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

    – Peter Cordes
    Apr 20 '15 at 8:29











  • I editted in another idea: you could hook cd to check / set your vars.

    – Peter Cordes
    Apr 20 '15 at 13:54











  • I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

    – Hongxu Chen
    Apr 20 '15 at 14:10











  • I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

    – Peter Cordes
    Apr 20 '15 at 21:26



















2














Yuch, too much maintenance and too much individual stuff.

I'd recommend putting most of the effort into having appropriately scoped names that are appropriate for the platform so you can just have all of them all of the time. PYTHONPATH is a good example... you're unlikely to want to repurpose it for a Ruby project... You can group and mark the group with comments in the .bashrc to ease maintenance.

It is not always possible to do that, i.e.. when there is conflict (plus it requires editing and not using discrete files) and sometimes you will need a framework specific setup file. One approach to that is to have aliases setup to run them, e.g.



e.g.



alias pp='. ~/pp.setup' # For using Python
alias rb='. /rb.setup' # For using Ruby


You could also create a function, something like 'switcher' that uses/sets a variable and just switches using a parameter passed in, or just toggles to what isn't current.






share|improve this answer
























  • This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

    – Peter Cordes
    Apr 20 '15 at 21:28



















1














There are management tools such as modules, that allow dynamic modification of a user's environment... though this one is no longer developed; last version is from 2012



Example:



$ module load gcc/3.1.1
$ which gcc
/usr/local/gcc/3.1.1/linux/bin/gcc





share|improve this answer































    0














    Inspired by @Peter Cordes and @Michael Durrant's answers, I came up with a limited and lightweight solution for my special case.



    Firstly let me re-illustrate my real issues.




    I need to use different llvm related executables (clang, llvm-config, etc) that are under project local directories, and I need to use 1 default version for general purpose (compiling, etc). I also need to need to use different python modules (llvm python bindings) inside different local directories.




    Since all my llvm related projects are built with similar directory structures, I specify the llvm version related environment variable (MY_LLVM_VERSION) and add the directories to PATH and PYTHONPATH. I used a function named _my_llvm_version that customize the variable interactively. As functions only have effects inside it, I use aliases to do the real source work. Then let MY_LLVM_VERSION defaults to my commonly used one (git). These are all inside ~/.zlocal that will be sourced for an interactive zsh. (Full file is here). By sourcing ~/.zlocal, I'm able to change PATH and PYTHONPATH according to MY_LLVM_VERSION.



    function _my_llvm_version() {
    available=("3.3" "3.4" "3.5" "git")
    USAGE="my_llvm_version 3.3|3.4|3.5|git"
    if [ $# -ne 1 ] || ! (( ${available[(I)${1}]} )); then
    echo "usage: $USAGE"
    fi
    MY_LLVM_VERSION="$1"
    }
    alias my_ll33='_my_llvm_version 3.3;source ~/.zlocal'
    alias my_ll34='_my_llvm_version 3.4;source ~/.zlocal'
    alias my_ll35='_my_llvm_version 3.5;source ~/.zlocal'
    alias my_llgit='_my_llvm_version git;source ~/.zlocal'
    : ${MY_LLVM_VERSION:=git}


    I think it should be more maintainable and do not invoke a child shell. It should be useful to add llvm version to PS1 area, but currently I do not need that.



    Of course, this solution is not general and not a real solution to my original question.






    share|improve this answer































      0














      You can use direnv to load environment variables on directory change. From its homepage:




      direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.




      I am using it with the xonsh shell (via a small additional plugin) and it works excellent.






      share|improve this answer
























        Your Answer








        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "106"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f192118%2fis-there-a-nice-way-to-set-directory-project-local-environment-variables%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        0














        You can source any file you like, it doesn't have to be .zshrc. You could make an env-setup script for each different project, and keep it in the project directory.



        If you want to be able to start new shells and have them load the env settings, you have a couple options:




        • Always start your shells in the project directory, and have your .zshrc [[ -e ./PROJECT-ENV.sh ]] && source ./PROJECT-ENV.sh (which you keep there). DANGEROUS: starting a new shell in a directory with hostile contents runs whatever code is in the file you source.


        • .zshrc: source ~/current-project.sh. update current project with ln -sf "$PWD/THIS-PROJECT-ENV.sh ~/current-project.sh


        If only a few commands for each project need the env vars set, you could make wrapper scripts for them that set the variables, and then leave your shell rc file untouched.



        Another idea: you could hack something into PROMPT_COMMAND, which runs before every prompt is displayed. Or hook cd/pushd/popd by writing shell functions with those names which check/set env vars and then run builtin cd.






        share|improve this answer


























        • Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

          – Hongxu Chen
          Apr 20 '15 at 6:12











        • or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

          – Peter Cordes
          Apr 20 '15 at 8:29











        • I editted in another idea: you could hook cd to check / set your vars.

          – Peter Cordes
          Apr 20 '15 at 13:54











        • I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

          – Hongxu Chen
          Apr 20 '15 at 14:10











        • I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

          – Peter Cordes
          Apr 20 '15 at 21:26
















        0














        You can source any file you like, it doesn't have to be .zshrc. You could make an env-setup script for each different project, and keep it in the project directory.



        If you want to be able to start new shells and have them load the env settings, you have a couple options:




        • Always start your shells in the project directory, and have your .zshrc [[ -e ./PROJECT-ENV.sh ]] && source ./PROJECT-ENV.sh (which you keep there). DANGEROUS: starting a new shell in a directory with hostile contents runs whatever code is in the file you source.


        • .zshrc: source ~/current-project.sh. update current project with ln -sf "$PWD/THIS-PROJECT-ENV.sh ~/current-project.sh


        If only a few commands for each project need the env vars set, you could make wrapper scripts for them that set the variables, and then leave your shell rc file untouched.



        Another idea: you could hack something into PROMPT_COMMAND, which runs before every prompt is displayed. Or hook cd/pushd/popd by writing shell functions with those names which check/set env vars and then run builtin cd.






        share|improve this answer


























        • Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

          – Hongxu Chen
          Apr 20 '15 at 6:12











        • or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

          – Peter Cordes
          Apr 20 '15 at 8:29











        • I editted in another idea: you could hook cd to check / set your vars.

          – Peter Cordes
          Apr 20 '15 at 13:54











        • I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

          – Hongxu Chen
          Apr 20 '15 at 14:10











        • I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

          – Peter Cordes
          Apr 20 '15 at 21:26














        0












        0








        0







        You can source any file you like, it doesn't have to be .zshrc. You could make an env-setup script for each different project, and keep it in the project directory.



        If you want to be able to start new shells and have them load the env settings, you have a couple options:




        • Always start your shells in the project directory, and have your .zshrc [[ -e ./PROJECT-ENV.sh ]] && source ./PROJECT-ENV.sh (which you keep there). DANGEROUS: starting a new shell in a directory with hostile contents runs whatever code is in the file you source.


        • .zshrc: source ~/current-project.sh. update current project with ln -sf "$PWD/THIS-PROJECT-ENV.sh ~/current-project.sh


        If only a few commands for each project need the env vars set, you could make wrapper scripts for them that set the variables, and then leave your shell rc file untouched.



        Another idea: you could hack something into PROMPT_COMMAND, which runs before every prompt is displayed. Or hook cd/pushd/popd by writing shell functions with those names which check/set env vars and then run builtin cd.






        share|improve this answer















        You can source any file you like, it doesn't have to be .zshrc. You could make an env-setup script for each different project, and keep it in the project directory.



        If you want to be able to start new shells and have them load the env settings, you have a couple options:




        • Always start your shells in the project directory, and have your .zshrc [[ -e ./PROJECT-ENV.sh ]] && source ./PROJECT-ENV.sh (which you keep there). DANGEROUS: starting a new shell in a directory with hostile contents runs whatever code is in the file you source.


        • .zshrc: source ~/current-project.sh. update current project with ln -sf "$PWD/THIS-PROJECT-ENV.sh ~/current-project.sh


        If only a few commands for each project need the env vars set, you could make wrapper scripts for them that set the variables, and then leave your shell rc file untouched.



        Another idea: you could hack something into PROMPT_COMMAND, which runs before every prompt is displayed. Or hook cd/pushd/popd by writing shell functions with those names which check/set env vars and then run builtin cd.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Apr 20 '15 at 13:54

























        answered Apr 19 '15 at 14:26









        Peter CordesPeter Cordes

        4,5731434




        4,5731434













        • Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

          – Hongxu Chen
          Apr 20 '15 at 6:12











        • or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

          – Peter Cordes
          Apr 20 '15 at 8:29











        • I editted in another idea: you could hook cd to check / set your vars.

          – Peter Cordes
          Apr 20 '15 at 13:54











        • I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

          – Hongxu Chen
          Apr 20 '15 at 14:10











        • I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

          – Peter Cordes
          Apr 20 '15 at 21:26



















        • Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

          – Hongxu Chen
          Apr 20 '15 at 6:12











        • or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

          – Peter Cordes
          Apr 20 '15 at 8:29











        • I editted in another idea: you could hook cd to check / set your vars.

          – Peter Cordes
          Apr 20 '15 at 13:54











        • I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

          – Hongxu Chen
          Apr 20 '15 at 14:10











        • I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

          – Peter Cordes
          Apr 20 '15 at 21:26

















        Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

        – Hongxu Chen
        Apr 20 '15 at 6:12





        Yes, you are correct that wrapper is enough when only a few of commands are needed. child-shell with PROJECT-ENV.sh seems the most efficient way for me and the only trick is that I should remember to exit it.

        – Hongxu Chen
        Apr 20 '15 at 6:12













        or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

        – Peter Cordes
        Apr 20 '15 at 8:29





        or just source a different PROJECT-ENV.sh after you cd, but then you have the problem of remembering to change vars. Maybe have PROJECT-ENV.sh also modify your PS1, or make the build scripts for each project look for something so they can detect that you have the wrong setting when you do something common. Then you can fix your shell so everything works.

        – Peter Cordes
        Apr 20 '15 at 8:29













        I editted in another idea: you could hook cd to check / set your vars.

        – Peter Cordes
        Apr 20 '15 at 13:54





        I editted in another idea: you could hook cd to check / set your vars.

        – Peter Cordes
        Apr 20 '15 at 13:54













        I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

        – Hongxu Chen
        Apr 20 '15 at 14:10





        I think I'll choose to change PS1. Using PROMPT_COMMAND is too noisy; and changing cd is not optimal since sometimes I need to use the project settings but inside other external directories(e.g., for testing purposes).

        – Hongxu Chen
        Apr 20 '15 at 14:10













        I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

        – Peter Cordes
        Apr 20 '15 at 21:26





        I meant putting a function call in PROMPT_COMMAND to a function that checks your current directory, and updates env vars. But if you don't ALWAYS want your env vars to silently change (or non-silently), then that's not what you want.

        – Peter Cordes
        Apr 20 '15 at 21:26













        2














        Yuch, too much maintenance and too much individual stuff.

        I'd recommend putting most of the effort into having appropriately scoped names that are appropriate for the platform so you can just have all of them all of the time. PYTHONPATH is a good example... you're unlikely to want to repurpose it for a Ruby project... You can group and mark the group with comments in the .bashrc to ease maintenance.

        It is not always possible to do that, i.e.. when there is conflict (plus it requires editing and not using discrete files) and sometimes you will need a framework specific setup file. One approach to that is to have aliases setup to run them, e.g.



        e.g.



        alias pp='. ~/pp.setup' # For using Python
        alias rb='. /rb.setup' # For using Ruby


        You could also create a function, something like 'switcher' that uses/sets a variable and just switches using a parameter passed in, or just toggles to what isn't current.






        share|improve this answer
























        • This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

          – Peter Cordes
          Apr 20 '15 at 21:28
















        2














        Yuch, too much maintenance and too much individual stuff.

        I'd recommend putting most of the effort into having appropriately scoped names that are appropriate for the platform so you can just have all of them all of the time. PYTHONPATH is a good example... you're unlikely to want to repurpose it for a Ruby project... You can group and mark the group with comments in the .bashrc to ease maintenance.

        It is not always possible to do that, i.e.. when there is conflict (plus it requires editing and not using discrete files) and sometimes you will need a framework specific setup file. One approach to that is to have aliases setup to run them, e.g.



        e.g.



        alias pp='. ~/pp.setup' # For using Python
        alias rb='. /rb.setup' # For using Ruby


        You could also create a function, something like 'switcher' that uses/sets a variable and just switches using a parameter passed in, or just toggles to what isn't current.






        share|improve this answer
























        • This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

          – Peter Cordes
          Apr 20 '15 at 21:28














        2












        2








        2







        Yuch, too much maintenance and too much individual stuff.

        I'd recommend putting most of the effort into having appropriately scoped names that are appropriate for the platform so you can just have all of them all of the time. PYTHONPATH is a good example... you're unlikely to want to repurpose it for a Ruby project... You can group and mark the group with comments in the .bashrc to ease maintenance.

        It is not always possible to do that, i.e.. when there is conflict (plus it requires editing and not using discrete files) and sometimes you will need a framework specific setup file. One approach to that is to have aliases setup to run them, e.g.



        e.g.



        alias pp='. ~/pp.setup' # For using Python
        alias rb='. /rb.setup' # For using Ruby


        You could also create a function, something like 'switcher' that uses/sets a variable and just switches using a parameter passed in, or just toggles to what isn't current.






        share|improve this answer













        Yuch, too much maintenance and too much individual stuff.

        I'd recommend putting most of the effort into having appropriately scoped names that are appropriate for the platform so you can just have all of them all of the time. PYTHONPATH is a good example... you're unlikely to want to repurpose it for a Ruby project... You can group and mark the group with comments in the .bashrc to ease maintenance.

        It is not always possible to do that, i.e.. when there is conflict (plus it requires editing and not using discrete files) and sometimes you will need a framework specific setup file. One approach to that is to have aliases setup to run them, e.g.



        e.g.



        alias pp='. ~/pp.setup' # For using Python
        alias rb='. /rb.setup' # For using Ruby


        You could also create a function, something like 'switcher' that uses/sets a variable and just switches using a parameter passed in, or just toggles to what isn't current.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Apr 20 '15 at 14:05









        Michael DurrantMichael Durrant

        16.4k45121187




        16.4k45121187













        • This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

          – Peter Cordes
          Apr 20 '15 at 21:28



















        • This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

          – Peter Cordes
          Apr 20 '15 at 21:28

















        This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

        – Peter Cordes
        Apr 20 '15 at 21:28





        This is a great point. If possible, install your different versions of clang so you can run them as cc-clang3.2 or whatever, so you can use any version at any time just by running it.

        – Peter Cordes
        Apr 20 '15 at 21:28











        1














        There are management tools such as modules, that allow dynamic modification of a user's environment... though this one is no longer developed; last version is from 2012



        Example:



        $ module load gcc/3.1.1
        $ which gcc
        /usr/local/gcc/3.1.1/linux/bin/gcc





        share|improve this answer




























          1














          There are management tools such as modules, that allow dynamic modification of a user's environment... though this one is no longer developed; last version is from 2012



          Example:



          $ module load gcc/3.1.1
          $ which gcc
          /usr/local/gcc/3.1.1/linux/bin/gcc





          share|improve this answer


























            1












            1








            1







            There are management tools such as modules, that allow dynamic modification of a user's environment... though this one is no longer developed; last version is from 2012



            Example:



            $ module load gcc/3.1.1
            $ which gcc
            /usr/local/gcc/3.1.1/linux/bin/gcc





            share|improve this answer













            There are management tools such as modules, that allow dynamic modification of a user's environment... though this one is no longer developed; last version is from 2012



            Example:



            $ module load gcc/3.1.1
            $ which gcc
            /usr/local/gcc/3.1.1/linux/bin/gcc






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 24 '16 at 15:55









            Jakub NarębskiJakub Narębski

            69521029




            69521029























                0














                Inspired by @Peter Cordes and @Michael Durrant's answers, I came up with a limited and lightweight solution for my special case.



                Firstly let me re-illustrate my real issues.




                I need to use different llvm related executables (clang, llvm-config, etc) that are under project local directories, and I need to use 1 default version for general purpose (compiling, etc). I also need to need to use different python modules (llvm python bindings) inside different local directories.




                Since all my llvm related projects are built with similar directory structures, I specify the llvm version related environment variable (MY_LLVM_VERSION) and add the directories to PATH and PYTHONPATH. I used a function named _my_llvm_version that customize the variable interactively. As functions only have effects inside it, I use aliases to do the real source work. Then let MY_LLVM_VERSION defaults to my commonly used one (git). These are all inside ~/.zlocal that will be sourced for an interactive zsh. (Full file is here). By sourcing ~/.zlocal, I'm able to change PATH and PYTHONPATH according to MY_LLVM_VERSION.



                function _my_llvm_version() {
                available=("3.3" "3.4" "3.5" "git")
                USAGE="my_llvm_version 3.3|3.4|3.5|git"
                if [ $# -ne 1 ] || ! (( ${available[(I)${1}]} )); then
                echo "usage: $USAGE"
                fi
                MY_LLVM_VERSION="$1"
                }
                alias my_ll33='_my_llvm_version 3.3;source ~/.zlocal'
                alias my_ll34='_my_llvm_version 3.4;source ~/.zlocal'
                alias my_ll35='_my_llvm_version 3.5;source ~/.zlocal'
                alias my_llgit='_my_llvm_version git;source ~/.zlocal'
                : ${MY_LLVM_VERSION:=git}


                I think it should be more maintainable and do not invoke a child shell. It should be useful to add llvm version to PS1 area, but currently I do not need that.



                Of course, this solution is not general and not a real solution to my original question.






                share|improve this answer




























                  0














                  Inspired by @Peter Cordes and @Michael Durrant's answers, I came up with a limited and lightweight solution for my special case.



                  Firstly let me re-illustrate my real issues.




                  I need to use different llvm related executables (clang, llvm-config, etc) that are under project local directories, and I need to use 1 default version for general purpose (compiling, etc). I also need to need to use different python modules (llvm python bindings) inside different local directories.




                  Since all my llvm related projects are built with similar directory structures, I specify the llvm version related environment variable (MY_LLVM_VERSION) and add the directories to PATH and PYTHONPATH. I used a function named _my_llvm_version that customize the variable interactively. As functions only have effects inside it, I use aliases to do the real source work. Then let MY_LLVM_VERSION defaults to my commonly used one (git). These are all inside ~/.zlocal that will be sourced for an interactive zsh. (Full file is here). By sourcing ~/.zlocal, I'm able to change PATH and PYTHONPATH according to MY_LLVM_VERSION.



                  function _my_llvm_version() {
                  available=("3.3" "3.4" "3.5" "git")
                  USAGE="my_llvm_version 3.3|3.4|3.5|git"
                  if [ $# -ne 1 ] || ! (( ${available[(I)${1}]} )); then
                  echo "usage: $USAGE"
                  fi
                  MY_LLVM_VERSION="$1"
                  }
                  alias my_ll33='_my_llvm_version 3.3;source ~/.zlocal'
                  alias my_ll34='_my_llvm_version 3.4;source ~/.zlocal'
                  alias my_ll35='_my_llvm_version 3.5;source ~/.zlocal'
                  alias my_llgit='_my_llvm_version git;source ~/.zlocal'
                  : ${MY_LLVM_VERSION:=git}


                  I think it should be more maintainable and do not invoke a child shell. It should be useful to add llvm version to PS1 area, but currently I do not need that.



                  Of course, this solution is not general and not a real solution to my original question.






                  share|improve this answer


























                    0












                    0








                    0







                    Inspired by @Peter Cordes and @Michael Durrant's answers, I came up with a limited and lightweight solution for my special case.



                    Firstly let me re-illustrate my real issues.




                    I need to use different llvm related executables (clang, llvm-config, etc) that are under project local directories, and I need to use 1 default version for general purpose (compiling, etc). I also need to need to use different python modules (llvm python bindings) inside different local directories.




                    Since all my llvm related projects are built with similar directory structures, I specify the llvm version related environment variable (MY_LLVM_VERSION) and add the directories to PATH and PYTHONPATH. I used a function named _my_llvm_version that customize the variable interactively. As functions only have effects inside it, I use aliases to do the real source work. Then let MY_LLVM_VERSION defaults to my commonly used one (git). These are all inside ~/.zlocal that will be sourced for an interactive zsh. (Full file is here). By sourcing ~/.zlocal, I'm able to change PATH and PYTHONPATH according to MY_LLVM_VERSION.



                    function _my_llvm_version() {
                    available=("3.3" "3.4" "3.5" "git")
                    USAGE="my_llvm_version 3.3|3.4|3.5|git"
                    if [ $# -ne 1 ] || ! (( ${available[(I)${1}]} )); then
                    echo "usage: $USAGE"
                    fi
                    MY_LLVM_VERSION="$1"
                    }
                    alias my_ll33='_my_llvm_version 3.3;source ~/.zlocal'
                    alias my_ll34='_my_llvm_version 3.4;source ~/.zlocal'
                    alias my_ll35='_my_llvm_version 3.5;source ~/.zlocal'
                    alias my_llgit='_my_llvm_version git;source ~/.zlocal'
                    : ${MY_LLVM_VERSION:=git}


                    I think it should be more maintainable and do not invoke a child shell. It should be useful to add llvm version to PS1 area, but currently I do not need that.



                    Of course, this solution is not general and not a real solution to my original question.






                    share|improve this answer













                    Inspired by @Peter Cordes and @Michael Durrant's answers, I came up with a limited and lightweight solution for my special case.



                    Firstly let me re-illustrate my real issues.




                    I need to use different llvm related executables (clang, llvm-config, etc) that are under project local directories, and I need to use 1 default version for general purpose (compiling, etc). I also need to need to use different python modules (llvm python bindings) inside different local directories.




                    Since all my llvm related projects are built with similar directory structures, I specify the llvm version related environment variable (MY_LLVM_VERSION) and add the directories to PATH and PYTHONPATH. I used a function named _my_llvm_version that customize the variable interactively. As functions only have effects inside it, I use aliases to do the real source work. Then let MY_LLVM_VERSION defaults to my commonly used one (git). These are all inside ~/.zlocal that will be sourced for an interactive zsh. (Full file is here). By sourcing ~/.zlocal, I'm able to change PATH and PYTHONPATH according to MY_LLVM_VERSION.



                    function _my_llvm_version() {
                    available=("3.3" "3.4" "3.5" "git")
                    USAGE="my_llvm_version 3.3|3.4|3.5|git"
                    if [ $# -ne 1 ] || ! (( ${available[(I)${1}]} )); then
                    echo "usage: $USAGE"
                    fi
                    MY_LLVM_VERSION="$1"
                    }
                    alias my_ll33='_my_llvm_version 3.3;source ~/.zlocal'
                    alias my_ll34='_my_llvm_version 3.4;source ~/.zlocal'
                    alias my_ll35='_my_llvm_version 3.5;source ~/.zlocal'
                    alias my_llgit='_my_llvm_version git;source ~/.zlocal'
                    : ${MY_LLVM_VERSION:=git}


                    I think it should be more maintainable and do not invoke a child shell. It should be useful to add llvm version to PS1 area, but currently I do not need that.



                    Of course, this solution is not general and not a real solution to my original question.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Apr 21 '15 at 12:32









                    Hongxu ChenHongxu Chen

                    2,08951624




                    2,08951624























                        0














                        You can use direnv to load environment variables on directory change. From its homepage:




                        direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.




                        I am using it with the xonsh shell (via a small additional plugin) and it works excellent.






                        share|improve this answer




























                          0














                          You can use direnv to load environment variables on directory change. From its homepage:




                          direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.




                          I am using it with the xonsh shell (via a small additional plugin) and it works excellent.






                          share|improve this answer


























                            0












                            0








                            0







                            You can use direnv to load environment variables on directory change. From its homepage:




                            direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.




                            I am using it with the xonsh shell (via a small additional plugin) and it works excellent.






                            share|improve this answer













                            You can use direnv to load environment variables on directory change. From its homepage:




                            direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.




                            I am using it with the xonsh shell (via a small additional plugin) and it works excellent.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Mar 6 at 1:53









                            halloleohalloleo

                            1368




                            1368






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f192118%2fis-there-a-nice-way-to-set-directory-project-local-environment-variables%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                                is 'sed' thread safe

                                How to make a Squid Proxy server?