Source vs execution
./script.sh
bash script.sh
source script.sh
. script.sh
Basic usage
source ~/.bashrc
. ~/.bashrc
source script.sh arg1 arg2
. script.sh arg1 arg2
Common use cases
Reload shell configuration
source ~/.bashrc
. ~/.bashrc
source ~/.zshrc
Load environment variables
source .env
. .env
set -a
source .env
set +a
Apply aliases/functions
alias ll='ls -lah'
alias gs='git status'
source ~/.bash_aliases
Difference from execution
Execution (./script.sh)
export VAR=value
cd /tmp
./script.sh
echo $VAR
pwd
Source (source script.sh)
export VAR=value
cd /tmp
source script.sh
echo $VAR
pwd
Return vs exit
return 0
exit 0
Safe script
#!/bin/bash
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
exit_cmd="exit"
else
exit_cmd="return"
fi
$exit_cmd 0
Load configuration files
User profile
source /etc/profile
source ~/.bash_profile
source ~/.bashrc
Project configuration
#!/bin/bash
export PROJECT_ROOT=/path/to/project
export PATH=$PROJECT_ROOT/bin:$PATH
alias build='make -C $PROJECT_ROOT'
cd $PROJECT_ROOT
Conditional sourcing
[ -f ~/.bash_custom ] && source ~/.bash_custom
if [ -f ~/.bash_aliases ]; then
source ~/.bash_aliases
fi
for file in ~/.bash_*; do
[ -f "$file" ] && source "$file"
done
Source in scripts
#!/bin/bash
source /etc/myapp/config.sh
source ./lib/functions.sh
echo "Database: $DB_HOST"
my_function arg1 arg2
Virtual environments
Python
source venv/bin/activate
. venv/bin/activate
deactivate
Node.js (nvm)
source ~/.nvm/nvm.sh
nvm use 16
Function libraries
log_info() {
echo "[INFO] $*"
}
log_error() {
echo "[ERROR] $*" >&2
}
source lib/functions.sh
log_info "Starting process"
log_error "Something went wrong"
Configuration management
export DB_HOST=localhost
export DB_PORT=5432
export DEBUG=true
export DB_HOST=prod-db.example.com
export DB_PORT=5432
export DEBUG=false
ENV=${1:-development}
source "config/${ENV}.sh"
Error handling
source config.sh || exit 1
source config.sh || {
echo "Failed to load config"
exit 1
}
source optional-config.sh 2>/dev/null || true
Security considerations
CONFIG_FILE="$1"
[ -f "$CONFIG_FILE" ] || {
echo "Config file not found"
exit 1
}
[ "$(stat -c %U "$CONFIG_FILE")" = "root" ] || {
echo "Config must be owned by root"
exit 1
}
[ "$(stat -c %a "$CONFIG_FILE")" = "600" ] || {
echo "Config must be 600"
exit 1
}
source "$CONFIG_FILE"
Common patterns
Load all configs
for config in /etc/myapp/*.sh; do
[ -f "$config" ] && source "$config"
done
Cascade configuration
source /etc/app/defaults.sh
source /etc/app/config.sh
source ~/.apprc
source ./.app-local
Profile snippets
if [ -d ~/.bashrc.d ]; then
for rc in ~/.bashrc.d/*.sh; do
[ -f "$rc" ] && . "$rc"
done
fi
unset rc
Troubleshooting
Variable not set
source script.sh
echo $?
set -x
source script.sh
set +x
Path issues
source /absolute/path/to/script.sh
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$DIR/lib/functions.sh"
Already sourced check
if [ -n "$MYLIB_LOADED" ]; then
return
fi
export MYLIB_LOADED=1
Best practices
source ~/.bashrc
source .env
./build.sh
bash deploy.sh
[ -f config.sh ] && source config.sh
source "$(dirname "$0")/lib/functions.sh"
source config/database.sh
source critical-config.sh || exit 1
source optional-config.sh || true
Quick reference
source file.sh
. file.sh
source ~/.bashrc
source ~/.bash_aliases
source .env
source venv/bin/activate
[ -f file.sh ] && source file.sh
source file.sh || exit 1
if [ "${BASH_SOURCE[0]}" != "${0}" ]; then
echo "Script is being sourced"
fi