Introduction

Hello! Today I’ll explain the source command.

The source command loads configuration files or executes scripts in the current shell. You know when you edit .bashrc and think “I want to apply changes without restarting the terminal!”? That’s when you use this.

What is the source Command?

The source command executes a specified file in the current shell.

When you normally run a script, it starts a new shell process. But with source, it runs within your current shell. So variables and functions remain in your current shell.

Super handy, right?

Basic Syntax

1
source filename [arguments...]

or

1
. filename [arguments...]

A single period works too. It’s the POSIX shell compatible way.

Main Use Cases

Use Case Description
Load config files Reload .bashrc or .bash_profile
Variable definition files Load common variable definitions
Function libraries Import functions for scripts
Environment setup Set project-specific environment variables

Usage Examples

Example 1: Reload .bashrc

1
source ~/.bashrc

or

1
. ~/.bashrc

Explanation: After editing .bashrc, you can apply settings without restarting the terminal. I use this a lot.

Example 2: Load Environment Variable File

First, create an environment variable file.

1
2
3
4
5
# Contents of env_vars.sh
export DB_HOST="localhost"
export DB_PORT="5432"
export DB_NAME="myapp"
export API_KEY="secret123"

Load it.

1
2
source env_vars.sh
echo $DB_HOST

Output:

1
localhost

Variables are now set in the current shell.

Example 3: Load Function Library

1
2
3
4
5
6
7
8
# Contents of utils.sh
log_info() {
    echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}

Use in a script:

1
2
3
4
5
#!/bin/bash
source utils.sh

log_info "Starting process"
log_error "An error occurred"

Output:

1
2
[INFO] 2025-10-26 07:03:00 - Starting process
[ERROR] 2025-10-26 07:03:00 - An error occurred

Example 4: Project Configuration File

1
2
3
4
5
6
7
# project_config.sh
PROJECT_ROOT="/home/user/myproject"
export PATH="$PROJECT_ROOT/bin:$PATH"
export PYTHONPATH="$PROJECT_ROOT/lib:$PYTHONPATH"

alias build="cd $PROJECT_ROOT && make"
alias test="cd $PROJECT_ROOT && pytest"

Load when entering project directory:

1
2
3
cd ~/myproject
source project_config.sh
build  # Alias works!

Example 5: source with Arguments

1
2
3
4
5
6
7
8
9
# Contents of config.sh
ENV=$1
echo "Environment: $ENV"

if [ "$ENV" = "production" ]; then
    export API_URL="https://api.example.com"
else
    export API_URL="http://localhost:3000"
fi

Execute:

1
2
source config.sh production
echo $API_URL

Output:

1
2
Environment: production
https://api.example.com

Tips & Notes

Difference Between source and ./

1
2
3
4
5
6
7
# Run with ./ (executes in a new shell)
./script.sh
echo $MY_VAR  # Variable doesn't persist

# Run with source (executes in current shell)
source script.sh
echo $MY_VAR  # Variable is available!

With ./, variables disappear when the script ends. With source, they remain.

Error Handling

If the file is not found with source, you get an error.

1
2
3
4
5
6
# Safe way to load
if [ -f "$HOME/.my_config" ]; then
    source "$HOME/.my_config"
else
    echo "Configuration file not found"
fi

Path Specification

Both relative and absolute paths work.

1
2
3
4
5
6
7
8
# Relative path
source ./config.sh

# Absolute path
source /etc/my_app/config.sh

# Home directory
source ~/.bashrc

Security Warning

Sourcing untrusted files is dangerous. The file contents execute in your current shell, so malicious code can harm your system.

1
2
3
4
# Don't source downloaded files immediately!
# Always check the contents first
cat suspicious_file.sh  # Check contents
source suspicious_file.sh

Practical Usage

Structuring .bashrc

When .bashrc gets long, you can split it by functionality.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# ~/.bashrc contents
# Aliases
if [ -f ~/.bash_aliases ]; then
    source ~/.bash_aliases
fi

# Functions
if [ -f ~/.bash_functions ]; then
    source ~/.bash_functions
fi

# Project-specific settings
if [ -f ~/.bash_projects ]; then
    source ~/.bash_projects
fi

Makes it easier to maintain.

Switching Development Environments

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# dev_env.sh
source_env() {
    local env=$1
    if [ -f "$HOME/.envs/${env}.sh" ]; then
        source "$HOME/.envs/${env}.sh"
        echo "Loaded environment '$env'"
    else
        echo "Environment '$env' not found"
        return 1
    fi
}

# Usage
# source_env production
# source_env staging
# source_env development

Node.js nvm

nvm (Node Version Manager) also uses source.

1
2
3
# Initialize nvm (put in .bashrc)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"

Summary

Key points about the source command:

  • Executes configuration files in the current shell
  • . (period) has the same meaning
  • Variables and functions remain in the current shell
  • Super useful for reloading .bashrc
  • Always check file contents before executing

When you edit configuration files, use source to apply changes immediately. Remember this - it’s really handy!