0

I have following 2 files:

file cd2vcaa (in path):

#! /bin/bash
cd /var/cache/apt/archives

file test.sh (in current directory):

#! /bin/bash
. cd2vcaa

From terminal, I am able to change directory with . cd2vcaa but not with ./test.sh

~$ cd2vcaa                        <-- no effect
~$ . cd2vcaa                      <-- changes directory
/var/cache/apt/archives$ cd       <-- back to home directory
~$ ./test.sh                      <-- does not change directory though no error - why?
~$

Why is . cd2vcaa working from terminal but from within another script? How can this problem be solved?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
rnso
  • 23,686
  • 25
  • 112
  • 234

1 Answers1

1

The test.sh runs in a separate shell when you invoke it using ./test.sh, so although the sourcing inside test.sh means that the cd command will affect the current directory in the shell in which test.sh runs, so for example any commands added at the end of test.sh would run with current directory /var/cache/apt/archives, it will not affect the parent shell (your login session).

If you invoke the test.sh by sourcing it (. test.sh), then no sub-shell is launched at either stage, and the directory is changed in your login session.

As discussed in the comments, if the aim is simply to have use of an interactive shell which is cd-ed to the specified directory (not necessarily the parent shell), then one option is just to put bash at the end of the test.sh in order to start an interactive subshell after the cd command has been run. On exit from this subshell, control will return to the login shell, still in its original working directory.

alani
  • 12,573
  • 2
  • 13
  • 23
  • I want to run `./test.sh` and that should change directory when test.sh ends. – rnso Jun 07 '20 at 07:58
  • @rnso That is not going to be possible. If you can provide more detail of _why_ you want to run `./test.sh` and it is not adequate for you to run `. ./test.sh` instead, then maybe someone can suggest a suitable workaround. – alani Jun 07 '20 at 08:00
  • Its simple. I want a script to update my system and then leave me in archives folder at the end. I want to check `.deb` files there so that I can delete them if needed. – rnso Jun 07 '20 at 08:06
  • Can using a function help? As in accepted answer here: https://stackoverflow.com/questions/874452/change-the-current-directory-from-a-bash-script – rnso Jun 07 '20 at 08:08
  • Would it meet your requirements if it launched an interactive subshell at the end that was `cd`-ed to the archives folder? You could achieve this by putting just `bash` inside your `test.sh` at the end. Obviously when you exit from this subshell, you will return to the original login shell, not immediately log out completely. If you don't want this, then using a function (or an alias) might be an alternative solution, but you will still have to source something to define the function (although this will only need to be done once, e.g. in your `$HOME/.bashrc`. – alani Jun 07 '20 at 08:18
  • Putting `bash` at end of script is a simple and easy solution for my purposes. If you put his in above answer, I will accept it. – rnso Jun 07 '20 at 11:39
  • @rnso I've added a final paragraph about it. – alani Jun 07 '20 at 12:16