Execute bash scripts on entering a directory

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
35
down vote

favorite
13












What is the best way to execute a script when entering into a directory?
When I move into a new directory I would like bash to execute the projectSettings.bash script much like RVM does.










share|improve this question



















  • 2




    Into every directory, or selected ones? And the same script for each, or not?
    – enzotib
    Sep 24 '11 at 19:50










  • Every directory. The script in the directory named projectSettings.bash if it exists.
    – Prospero
    Sep 24 '11 at 19:54










  • Similar question on Stack Overflow
    – Gilles
    Feb 26 '15 at 23:41














up vote
35
down vote

favorite
13












What is the best way to execute a script when entering into a directory?
When I move into a new directory I would like bash to execute the projectSettings.bash script much like RVM does.










share|improve this question



















  • 2




    Into every directory, or selected ones? And the same script for each, or not?
    – enzotib
    Sep 24 '11 at 19:50










  • Every directory. The script in the directory named projectSettings.bash if it exists.
    – Prospero
    Sep 24 '11 at 19:54










  • Similar question on Stack Overflow
    – Gilles
    Feb 26 '15 at 23:41












up vote
35
down vote

favorite
13









up vote
35
down vote

favorite
13






13





What is the best way to execute a script when entering into a directory?
When I move into a new directory I would like bash to execute the projectSettings.bash script much like RVM does.










share|improve this question















What is the best way to execute a script when entering into a directory?
When I move into a new directory I would like bash to execute the projectSettings.bash script much like RVM does.







bash shell-script cd-command






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 24 '11 at 19:53









Gilles

509k12010061535




509k12010061535










asked Sep 24 '11 at 19:39









Prospero

1,74062445




1,74062445







  • 2




    Into every directory, or selected ones? And the same script for each, or not?
    – enzotib
    Sep 24 '11 at 19:50










  • Every directory. The script in the directory named projectSettings.bash if it exists.
    – Prospero
    Sep 24 '11 at 19:54










  • Similar question on Stack Overflow
    – Gilles
    Feb 26 '15 at 23:41












  • 2




    Into every directory, or selected ones? And the same script for each, or not?
    – enzotib
    Sep 24 '11 at 19:50










  • Every directory. The script in the directory named projectSettings.bash if it exists.
    – Prospero
    Sep 24 '11 at 19:54










  • Similar question on Stack Overflow
    – Gilles
    Feb 26 '15 at 23:41







2




2




Into every directory, or selected ones? And the same script for each, or not?
– enzotib
Sep 24 '11 at 19:50




Into every directory, or selected ones? And the same script for each, or not?
– enzotib
Sep 24 '11 at 19:50












Every directory. The script in the directory named projectSettings.bash if it exists.
– Prospero
Sep 24 '11 at 19:54




Every directory. The script in the directory named projectSettings.bash if it exists.
– Prospero
Sep 24 '11 at 19:54












Similar question on Stack Overflow
– Gilles
Feb 26 '15 at 23:41




Similar question on Stack Overflow
– Gilles
Feb 26 '15 at 23:41










2 Answers
2






active

oldest

votes

















up vote
46
down vote



accepted










You can make cd a function (and pop and pushd), and make it detect if you enter that particular directory.



cd () builtin cd "$@" && chpwd; 
pushd () builtin pushd "$@" && chpwd;
popd () builtin popd "$@" && chpwd;
unset_all_project_settings ()
# do whatever it takes to undo the effect of projectSettings.bash,
# e.g. unset variables, remove PATH elements, etc.

chpwd () /some/other/directory) . ./projectSettings.bash;;
*) unset_all_project_settings;;
esac



Do not do this in directories that you haven't whitelisted, because it would make it very easy for someone to trick you into running arbitrary code — send you an archive, so you unzip it, change into the directory it created, and you've now run the attacker's code.



I don't recommend this approach, because it means the script will be executed even if you enter that directory for some reason that's unrelated to working on the project. I suggest having a specific function that changes to the project directory and sources the settings script.



myproj () 
cd /some/directory && . ./projectSettings.bash






share|improve this answer


















  • 1




    I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
    – Prospero
    Oct 2 '11 at 23:21







  • 1




    I was completely wrong and apologize. RVM was overloading cd.
    – Prospero
    Oct 7 '11 at 14:22







  • 5




    (removed some tangential pro/anti-Ruby stuff from this comment thread)
    – Michael Mrozek♦
    Jul 25 '12 at 21:04






  • 1




    in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
    – spider
    Sep 18 '15 at 9:57







  • 5




    @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
    – Gilles
    Sep 18 '15 at 10:11

















up vote
0
down vote













direnv might be what you are looking for.



Here is an example taken from the official documentation:



$ cd ~/my_project
$ echo $FOO-nope
nope
$ echo export FOO=foo > .envrc
.envrc is not allowed
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FOO
$ echo $FOO-nope
foo
$ cd ..
direnv: unloading
direnv export: ~PATH
$ echo $FOO-nope
nope





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',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    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%2f21363%2fexecute-bash-scripts-on-entering-a-directory%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    46
    down vote



    accepted










    You can make cd a function (and pop and pushd), and make it detect if you enter that particular directory.



    cd () builtin cd "$@" && chpwd; 
    pushd () builtin pushd "$@" && chpwd;
    popd () builtin popd "$@" && chpwd;
    unset_all_project_settings ()
    # do whatever it takes to undo the effect of projectSettings.bash,
    # e.g. unset variables, remove PATH elements, etc.

    chpwd () /some/other/directory) . ./projectSettings.bash;;
    *) unset_all_project_settings;;
    esac



    Do not do this in directories that you haven't whitelisted, because it would make it very easy for someone to trick you into running arbitrary code — send you an archive, so you unzip it, change into the directory it created, and you've now run the attacker's code.



    I don't recommend this approach, because it means the script will be executed even if you enter that directory for some reason that's unrelated to working on the project. I suggest having a specific function that changes to the project directory and sources the settings script.



    myproj () 
    cd /some/directory && . ./projectSettings.bash






    share|improve this answer


















    • 1




      I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
      – Prospero
      Oct 2 '11 at 23:21







    • 1




      I was completely wrong and apologize. RVM was overloading cd.
      – Prospero
      Oct 7 '11 at 14:22







    • 5




      (removed some tangential pro/anti-Ruby stuff from this comment thread)
      – Michael Mrozek♦
      Jul 25 '12 at 21:04






    • 1




      in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
      – spider
      Sep 18 '15 at 9:57







    • 5




      @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
      – Gilles
      Sep 18 '15 at 10:11














    up vote
    46
    down vote



    accepted










    You can make cd a function (and pop and pushd), and make it detect if you enter that particular directory.



    cd () builtin cd "$@" && chpwd; 
    pushd () builtin pushd "$@" && chpwd;
    popd () builtin popd "$@" && chpwd;
    unset_all_project_settings ()
    # do whatever it takes to undo the effect of projectSettings.bash,
    # e.g. unset variables, remove PATH elements, etc.

    chpwd () /some/other/directory) . ./projectSettings.bash;;
    *) unset_all_project_settings;;
    esac



    Do not do this in directories that you haven't whitelisted, because it would make it very easy for someone to trick you into running arbitrary code — send you an archive, so you unzip it, change into the directory it created, and you've now run the attacker's code.



    I don't recommend this approach, because it means the script will be executed even if you enter that directory for some reason that's unrelated to working on the project. I suggest having a specific function that changes to the project directory and sources the settings script.



    myproj () 
    cd /some/directory && . ./projectSettings.bash






    share|improve this answer


















    • 1




      I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
      – Prospero
      Oct 2 '11 at 23:21







    • 1




      I was completely wrong and apologize. RVM was overloading cd.
      – Prospero
      Oct 7 '11 at 14:22







    • 5




      (removed some tangential pro/anti-Ruby stuff from this comment thread)
      – Michael Mrozek♦
      Jul 25 '12 at 21:04






    • 1




      in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
      – spider
      Sep 18 '15 at 9:57







    • 5




      @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
      – Gilles
      Sep 18 '15 at 10:11












    up vote
    46
    down vote



    accepted







    up vote
    46
    down vote



    accepted






    You can make cd a function (and pop and pushd), and make it detect if you enter that particular directory.



    cd () builtin cd "$@" && chpwd; 
    pushd () builtin pushd "$@" && chpwd;
    popd () builtin popd "$@" && chpwd;
    unset_all_project_settings ()
    # do whatever it takes to undo the effect of projectSettings.bash,
    # e.g. unset variables, remove PATH elements, etc.

    chpwd () /some/other/directory) . ./projectSettings.bash;;
    *) unset_all_project_settings;;
    esac



    Do not do this in directories that you haven't whitelisted, because it would make it very easy for someone to trick you into running arbitrary code — send you an archive, so you unzip it, change into the directory it created, and you've now run the attacker's code.



    I don't recommend this approach, because it means the script will be executed even if you enter that directory for some reason that's unrelated to working on the project. I suggest having a specific function that changes to the project directory and sources the settings script.



    myproj () 
    cd /some/directory && . ./projectSettings.bash






    share|improve this answer














    You can make cd a function (and pop and pushd), and make it detect if you enter that particular directory.



    cd () builtin cd "$@" && chpwd; 
    pushd () builtin pushd "$@" && chpwd;
    popd () builtin popd "$@" && chpwd;
    unset_all_project_settings ()
    # do whatever it takes to undo the effect of projectSettings.bash,
    # e.g. unset variables, remove PATH elements, etc.

    chpwd () /some/other/directory) . ./projectSettings.bash;;
    *) unset_all_project_settings;;
    esac



    Do not do this in directories that you haven't whitelisted, because it would make it very easy for someone to trick you into running arbitrary code — send you an archive, so you unzip it, change into the directory it created, and you've now run the attacker's code.



    I don't recommend this approach, because it means the script will be executed even if you enter that directory for some reason that's unrelated to working on the project. I suggest having a specific function that changes to the project directory and sources the settings script.



    myproj () 
    cd /some/directory && . ./projectSettings.bash







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 18 '15 at 10:12

























    answered Sep 24 '11 at 19:52









    Gilles

    509k12010061535




    509k12010061535







    • 1




      I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
      – Prospero
      Oct 2 '11 at 23:21







    • 1




      I was completely wrong and apologize. RVM was overloading cd.
      – Prospero
      Oct 7 '11 at 14:22







    • 5




      (removed some tangential pro/anti-Ruby stuff from this comment thread)
      – Michael Mrozek♦
      Jul 25 '12 at 21:04






    • 1




      in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
      – spider
      Sep 18 '15 at 9:57







    • 5




      @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
      – Gilles
      Sep 18 '15 at 10:11












    • 1




      I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
      – Prospero
      Oct 2 '11 at 23:21







    • 1




      I was completely wrong and apologize. RVM was overloading cd.
      – Prospero
      Oct 7 '11 at 14:22







    • 5




      (removed some tangential pro/anti-Ruby stuff from this comment thread)
      – Michael Mrozek♦
      Jul 25 '12 at 21:04






    • 1




      in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
      – spider
      Sep 18 '15 at 9:57







    • 5




      @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
      – Gilles
      Sep 18 '15 at 10:11







    1




    1




    I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
    – Prospero
    Oct 2 '11 at 23:21





    I only started in Ruby a little while ago. The RVM tool tho is completely in Bash and one of the best pieces of Bash magic I have seen. I think the answer is a little silly because one of the absolutely worse things you can ever do is over ride something like cd and there is with out doubt a better way. Even using $PROMPT_COMMAND is better!
    – Prospero
    Oct 2 '11 at 23:21





    1




    1




    I was completely wrong and apologize. RVM was overloading cd.
    – Prospero
    Oct 7 '11 at 14:22





    I was completely wrong and apologize. RVM was overloading cd.
    – Prospero
    Oct 7 '11 at 14:22





    5




    5




    (removed some tangential pro/anti-Ruby stuff from this comment thread)
    – Michael Mrozek♦
    Jul 25 '12 at 21:04




    (removed some tangential pro/anti-Ruby stuff from this comment thread)
    – Michael Mrozek♦
    Jul 25 '12 at 21:04




    1




    1




    in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
    – spider
    Sep 18 '15 at 9:57





    in the projectSettings.bash I suggest you to add a flag variable to not repeat the initialization in case you exit/re-enter the directory. So enclose everything in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. This is to avoid problems in case you do something PATH=/mytools/bin:$PATH kind of initialisation.
    – spider
    Sep 18 '15 at 9:57





    5




    5




    @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
    – Gilles
    Sep 18 '15 at 10:11




    @spider Rather there should be some kind of unset mechanism if you leave the directory. If you leave and reenter, you should get the settings back!
    – Gilles
    Sep 18 '15 at 10:11












    up vote
    0
    down vote













    direnv might be what you are looking for.



    Here is an example taken from the official documentation:



    $ cd ~/my_project
    $ echo $FOO-nope
    nope
    $ echo export FOO=foo > .envrc
    .envrc is not allowed
    $ direnv allow .
    direnv: reloading
    direnv: loading .envrc
    direnv export: +FOO
    $ echo $FOO-nope
    foo
    $ cd ..
    direnv: unloading
    direnv export: ~PATH
    $ echo $FOO-nope
    nope





    share|improve this answer
























      up vote
      0
      down vote













      direnv might be what you are looking for.



      Here is an example taken from the official documentation:



      $ cd ~/my_project
      $ echo $FOO-nope
      nope
      $ echo export FOO=foo > .envrc
      .envrc is not allowed
      $ direnv allow .
      direnv: reloading
      direnv: loading .envrc
      direnv export: +FOO
      $ echo $FOO-nope
      foo
      $ cd ..
      direnv: unloading
      direnv export: ~PATH
      $ echo $FOO-nope
      nope





      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        direnv might be what you are looking for.



        Here is an example taken from the official documentation:



        $ cd ~/my_project
        $ echo $FOO-nope
        nope
        $ echo export FOO=foo > .envrc
        .envrc is not allowed
        $ direnv allow .
        direnv: reloading
        direnv: loading .envrc
        direnv export: +FOO
        $ echo $FOO-nope
        foo
        $ cd ..
        direnv: unloading
        direnv export: ~PATH
        $ echo $FOO-nope
        nope





        share|improve this answer












        direnv might be what you are looking for.



        Here is an example taken from the official documentation:



        $ cd ~/my_project
        $ echo $FOO-nope
        nope
        $ echo export FOO=foo > .envrc
        .envrc is not allowed
        $ direnv allow .
        direnv: reloading
        direnv: loading .envrc
        direnv export: +FOO
        $ echo $FOO-nope
        foo
        $ cd ..
        direnv: unloading
        direnv export: ~PATH
        $ echo $FOO-nope
        nope






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jul 31 at 7:15









        navigaid

        10111




        10111



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f21363%2fexecute-bash-scripts-on-entering-a-directory%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay