LearnLinux FoundationsBash Shell Environment

source

source - a hands-on Linux lab on a real virtual machine.

Run a script in the CURRENT shell with source, so its variables, aliases, functions, and directory changes stick in your session. The heart of the lesson is the contrast: a cd in a file leaves you put when run with bash (a subshell) but moves you for real when sourced. Covers source ~/.bashrc to reload config, the dot twin, loading variables, the missing-file error, the exit gotcha, and passing arguments.

You just added a handy shortcut to your ~/.bashrc, the file bash reads to set up every new terminal. Say you added an alias so that typing ll runs a long file listing. You save the file, you type ll, and bash says command not found. The shortcut is right there in the file. Why is it dead?

Because bash read that file ONCE, when this terminal opened, and it has not looked at it since. Your edit is on disk, but your running shell never saw it. There are two ways out. Close the terminal and open a new one, and it will read the file fresh. Or run one small command that tells your CURRENT shell to read the file again, right now, no new window. That command is source, and it is the subject of this lesson.

The black boxes below are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. A couple of outputs here, like your working directory or the exact lines in your ~/.bashrc, belong to the machine they were captured on. Those are shown as examples and marked so; yours will read differently. The commands you type are the same everywhere, and the command is what the sandbox grades.

Normally, when you run a script, bash starts a fresh, separate shell to run it in. That separate shell is called a subshell: a short-lived copy of your shell that does the work and then vanishes. Anything the script changed inside that copy, a variable, a directory move, dies with the copy. Your own shell never feels it.

source breaks that wall. Instead of spinning up a subshell, source runs the file's lines IN the shell you are sitting in, as if you had typed each line yourself. So anything the file sets up, a variable, an alias, a function, even a change of directory, STICKS in your session after the file finishes. That is the entire idea: source means "run this here, not over there."

source has a twin. A single dot, ., does the exact same thing: . FILE and source FILE are identical. The dot is the original POSIX spelling that works in every shell; source is the friendlier word bash added later. You will see both in the wild. They are the same command wearing two names.

Back to the broken alias from the cold open. You edited ~/.bashrc, but your shell has not re-read it. source ~/.bashrc tells the current shell to read that file again, top to bottom, right now. Every alias, variable, and function inside it is reapplied to THIS session, and your new ll shortcut springs to life with no new terminal.

Run the reload:

source ~/.bashrc

prompt: student@linuxcamp:~$ answer: source ~/.bashrc output: hint: Type the word source, a space, then the path to the file: source ~/.bashrc

No output, and that is exactly right: a clean reload is silent. Behind that silence, your shell just re-ran every line of ~/.bashrc, so the alias you added is now live. Type ll and it works. The file lives on disk; source is what carries its contents into the shell you are actually using. This one command, source ~/.bashrc, is the reason you almost never need to close a terminal after editing your config.

Here is the experiment that makes source click for good. Imagine a tiny file named go.sh with exactly one line inside it: cd /tmp. It moves you to the /tmp directory. Now watch what happens two different ways.

First, run it the ordinary way, with bash go.sh. That launches a subshell, the subshell moves ITSELF to /tmp, the script ends, the subshell vanishes, and you are handed back to your own shell, which never moved. Check where you are with pwd, which prints your working directory, and you are right where you started. The cd did not stick.

Before you run it, decide what you expect. Will pwd show /tmp, or the home directory you started in?

bash go.sh

prompt: student@linuxcamp:~$ answer: bash go.sh output: hint: Type bash, a space, then the script name: bash go.sh

Silent again, because the cd happened inside the subshell where you could not see it. The important part is where you are now. Run pwd and it prints /home/student, your starting directory, NOT /tmp. The subshell walked into /tmp, then took that fact to the grave when it exited. Your shell never left home. That is a subshell in one picture: it does the work in its own copy, and the copy's changes die with it.

Same file, go.sh, same single cd /tmp line inside it. This time, source it instead of running it with bash. Now the cd happens in YOUR shell, not a throwaway copy. When the file finishes, you are actually standing in /tmp.

Decide again before you run it: after source go.sh, will pwd say /tmp this time?

source go.sh

prompt: student@linuxcamp:~$ answer: source go.sh output: hint: Swap bash for source, same file: source go.sh

Silent, but this time everything moved. Run pwd now and it prints /tmp. Your prompt itself changes to show it: student@linuxcamp:/tmp$. Same one-line file, opposite result. bash go.sh left you home because the cd ran in a subshell; source go.sh moved you for real because the cd ran in your own shell. Hold onto this contrast. It is the whole lesson, and it is true for more than cd.

The same rule governs variables. Say a file called env.sh contains one line: export API_KEY=abc123. export makes a variable available to the shell and anything it runs.

Run that file with bash env.sh and, just like the cd, the variable is set inside a subshell that immediately vanishes. Your shell never receives it, so echo $API_KEY prints a blank line. source env.sh instead, and the export runs in your own shell, so API_KEY is now set in YOUR session and echo $API_KEY prints abc123. This is the everyday reason people source files: to load a set of variables, or a shared library of functions, straight into the shell they are working in.

Source the variables file, then read the variable back:

source env.sh

prompt: student@linuxcamp:~$ answer: source env.sh output: hint: Same pattern as before: source, a space, the file name: source env.sh

Silent, and now API_KEY lives in your session. Run echo $API_KEY and it prints abc123. Had you used bash env.sh, that same echo would have printed nothing, because the variable would have been set and lost inside a subshell. source is how you pour a file's settings into the shell you are actually using. Config, variables, functions: if you need them to STICK, you source the file.

source is simple, but two things trip people up. Both are worth seeing once so you recognise them instantly.

The first is a missing file. Point source at a file that is not there and it says so plainly:

prompt: student@linuxcamp:~$ answer: source nofile output: bash: source: nofile: No such file or directory hint: To reproduce the error on purpose, source a name that does not exist: source nofile

bash: source: nofile: No such file or directory means exactly what it says: source could not find a file named nofile in the current directory. Check the spelling and check that you are in the right folder, or give the full path, like source ~/.bashrc. This is the same "No such file or directory" you have met with other commands; here it just means the file you asked to run is not there.

The second gotcha is sharper, and it comes straight from what makes source powerful. Because a sourced file runs in YOUR shell, if that file contains an exit line, it does not end a subshell, it ends YOUR shell. Your whole terminal closes. Run the same file with bash and only the subshell would have exited, leaving you untouched. So be careful what you source: only source files you trust and understand, because whatever they do, they do to the shell you are sitting in.

One more form, so nothing surprises you later. Just like a normal script, a sourced file can take arguments. Anything you type after the file name becomes the file's positional arguments, $1, $2, and so on, available to the lines inside it.

The shape is source FILE arg1 arg2. You will not need this often, but when a shared setup file expects a value, this is how you hand it one:

source setup.sh prod 8080

prompt: student@linuxcamp:~$ answer: source setup.sh prod 8080 output: hint: source, the file, then the arguments separated by spaces: source setup.sh prod 8080

Inside setup.sh, $1 is now prod and $2 is 8080, exactly as if the file had been called as a normal script with those arguments, except everything it sets still lands in your current shell. Most of the time you will source a file with no arguments at all, like source ~/.bashrc. But knowing the arguments go on the end means a shared setup file will never confuse you.

Scaffolding off. No command is printed this time. You have every piece you need.

You just added a new alias to your ~/.bashrc. You do not want to close this terminal and open a fresh one. You want your current shell to read the config file again, right now, so the alias works immediately. Type the command that does exactly that.

prompt: student@linuxcamp:~$ answer: source ~/.bashrc output: hint: The command that runs a file in your CURRENT shell, pointed at your config file. Think source, then the path ~/.bashrc.

That is the move you will make more than any other with this command. source ~/.bashrc told your live shell to re-read the config file, so every alias, variable, and function inside it, including the one you just added, is applied to this session with no new window. You recalled the command from memory and pointed it at the right file, which is exactly the recall the real machine will ask of you.

You earned this cheat sheet. Every row is a form of source you just ran:

The one idea under all of it: source runs a file HERE, in your shell, not in a throwaway subshell. That is why a cd, a variable, or an alias from a sourced file survives, while the same file run with bash leaves your shell untouched.

Quick test to remember which is which: if you need a script's changes to LAST in your shell, source it. If you just want a script to do its job and leave your shell exactly as it was, run it with bash script.sh or ./script.sh. Sticking versus not sticking is the entire decision.

The practice terminal has shown you the shape of source. You have the reload move, source ~/.bashrc, and the dot twin .. You have the contrast that proves a sourced cd sticks while a bash-run one does not, plus loading variables, the two gotchas, and passing arguments. Every one of those you typed yourself.

The Bash Environment module ends with one real Linux machine, the Bash Environment capstone mission, and that is where you use source for real. A VM boots just for you, with its own live shell and config. It hands you objectives that use exactly what you practiced across this module: variables, aliases, PATH, your ~/.bashrc, and sourcing files to make changes take hold. One difference from here: the mission shows no commands. You read the objective, you recall the command, you type it. That recall is what makes it stick.

Finish the other Bash Environment lessons, then go make a change stick on a real shell.

Practice source in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.