[ACCEPTED]-Run bash script as source without source command-dot-source

Accepted answer
Score: 33

Bash forks and starts a subshell way before 5 it or your kernel even considers what it's 4 supposed to do in there. It's not something 3 you can "undo". So no, it's impossible.

Thankfully.

Look 2 into bash functions instead:

sup() {
    ...
}

Put that in your 1 ~/.bashrc.

Score: 25

When you are running a shell, there are 16 two ways to invoke a shell script:

  • Executing a script 15 spawns a new process inside which the script 14 is running. This is done by typing the script 13 name, if it is made executable and starts 12 with a

    #!/bin/bash
    line, or directly invoking
    /bin/bash mycmd.sh
  • Sourcing a script runs it inside its parent 11 shell (i.e. the one you are typing commands 10 into). This is done by typing

    source mycmd.sh
    or
    . mycmd.sh

So the cd 9 inside a shell script that isn't sourced 8 is never going to propagate to its parent shell, as 7 this would violate process isolation.

If 6 the cd is all you are interested about, you 5 can get rid of the script by using cd "shortcuts"... Take 4 a look into the bash doc, at the CDPATH 3 env var.

Otherwise, you can use an alias 2 to be able to type a single command, instead 1 of source or .:

alias mycmd="source mycmd.sh"
Score: 10

Create an alias for it:

alias sup=". ~/bin/sup"

Or along those lines.

See 4 also: Why doesn't cd work in a bash shell script?


Answering comment by counter-example: experimentation 3 with Korn Shell on Solaris 10 shows that 2 I can do:

$ pwd
/work1/jleffler
$ echo "cd /work5/atria" > $HOME/bin/yyy
$ alias yyy=". ~/bin/yyy"
$ yyy
$ pwd
/work5/atria
$

Experimentation with Bash (3.00.16) on 1 Solaris 10 also shows the same behaviour.


Score: 7

It is not possible to source a script in 7 your current environment if you sub-shell 6 the script at invoke.

However, you can check that script is sourced and 5 force the script to terminate if not:

if [ -z "$PS1" ] ; then
    echo "This script must be sourced. Use \"source <script>\" instead."
    exit
fi

The 4 same way, you can force a script not to be sourced but to be sub-shelled 3 instead (preserve current shell environment):

if [ "$PS1" ] ; then
    echo "This script cannot be sourced. Use \"./<script>\" instead."
    return
fi

Both 2 versions are available as gists: see please source and 1 don't source.

More Related questions