I have two scripts. One is :

if [ $1 = 1 ]; then 
cd ~/code/${dir}$2
echo $(pwd)

The above script changes directories even though there are several posts that say that since a script is run in a sub-shell it should have no effect on the executing shell.

Now I have another script:

mkdir -p $dir
cd $dir
wget http://somurl.com/archive.zip
unzip archive.zip

The above script unzips the file in the expected directory but leaves the calling shell in the same directory. What is the difference when cd is called in both scripts?

  • 1
    The first does not change the running shell's directory for me. It prints the path to ~/code/mydirsomething, but then after exiting I'm left back in my original directory. How are you testing it? Dec 17 '16 at 7:05
  • Can you provide a demostration of you running those scripts and the directory changing as a result?
    – user1686
    Dec 17 '16 at 10:35
  • Here is a demo: salilsurendran@salilsurendran-ThinkPad-P50:~$ myscript 1 4 /home/salilsurendran/code/mydir-1.6_4 salilsurendran@salilsurendran-ThinkPad-P50:~/code/mydir-1.6_4$ pwd /home/salilsurendran/code/mydir-1.6_4 salilsurendran@salilsurendran-ThinkPad-P50:~/code/mydir$ myscript 2 3 /home/salilsurendran/code/mydir3 salilsurendran@salilsurendran-ThinkPad-P50:~/code/mydir3$ pwd /home/salilsurendran/code/mydir3 salilsurendran@salilsurendran-ThinkPad-P50:~/code/mydir3$ Dec 18 '16 at 22:05
  • Please don't add information in the comments. Edit your question and include the extra information there instead. Comments are hard to read, easy to miss and can be deleted without warning. That said, your demo doesn't show that the parent shell changed directory. That;s the pwd output from the subshell running the script.
    – terdon
    Dec 21 '16 at 10:42

If I understand what your problem is, you could try executing the second script from the first, passing in expected directory. Like this.

script 1

echo "$TEST"
bash 2.sh "$TEST"

script 2

echo "$TEST"

Your first script does not change the directory. I don't know what makes you think it does, but cd inside an executed script will never affect the parent shell. That's just the way it works.

The only way it could change the directory of the parent shell is if you source it instead of executing it. I have saved your first script as foo.sh and run it from my $HOME:

$ pwd
$ foo.sh 1 
$ pwd

As you can see, the directory is changed inside the script, but the parent shell's PWD remains unchanged. Now, if you source it, it works as you seem to expect:

$ . ~/scripts/foo.sh
bash: [: =: unary operator expected
$ pwd

So, if you want your script to change the directory of its parent shell, you need to source it not execute it. However, if that's what you're trying to do, you want to write a function, not a script:

    if [ "$1" = "1" ]; then
    \cd "$targetDir"

Add the above to your ~/.bashrc and use that instead of a script. Functions always affect the shell that's running them so it will change your directory as you want it to.

Note that I am using \cd instead of cd. This is in case your cd is aliased to something. Also note that I have changed your script a little to avoid the bash: [: =: unary operator expected you were getting with your original approach. In shell scripts, it is essential to always quote your variables. In this case, when $1 was empty, the script was attempting to run:

$ if [ = 1 ]; then  targetDir="mydir-1.6_"; fi
bash: [: =: unary operator expected

Which, of course , gives an error since there's nothing to compare. By quoting $1 you are comparing the empty string and that will work as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.