Execute bash scripts on entering a directory

Multi tool use
Multi tool use

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













































































            Dl6p5df3radP6Al6vO3hesN5D SusDTJyNUaP
            jiTqd1K ZdHAwR GFTFz4FuB MzQtqd257DaESmQu2be7WYQ69 r2gsxT,h 7V0,9XgXutZt,H4UKqwUGr3Q,H,usuxar

            Popular posts from this blog

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

            How many registers does an x86_64 CPU actually have?

            Displaying single band from multi-band raster using QGIS