Some shell commands (such as cd
) affect the current shell and its child/descendent processes, but cannot affect the parent shell. When you run a script as an ordinary command (e.g., scriptname.sh
or ./scriptname.sh
), it runs in a separate shell process. When that shell process terminates, the effects of those commands go away. That's why scripts like yours often end with exec sh
, exec bash
, exec zsh
, or whatever — it causes the process that's in the new environment to persist, as an interactive shell.
If you don't want to do it that way, the only other approach is to run the script in your main, interactive shell. In bash, you can do this with
source scriptname.sh
or
. scriptname.sh
(You may need to use ./scriptname.sh
if the script is in the current directory.) I'm pretty sure zsh
has the same functionality. The syntax might be different; check the documentation for your shell.
If you have trouble remembering to do this (or if it gets cumbersome), considering defining an alias for it.