Skip to content

Instantly share code, notes, and snippets.

@a-magdy
Last active November 13, 2023 14:01
Show Gist options
  • Save a-magdy/0f6df1e0063efea9ab97bb9bc0c77bfa to your computer and use it in GitHub Desktop.
Save a-magdy/0f6df1e0063efea9ab97bb9bc0c77bfa to your computer and use it in GitHub Desktop.
export vars from .env file
#!/bin/bash
# Use grep to validate each line using regex (clears out comments, empty lines and validates that each line is in the format of env vars)
# Then send it out to sed, to append export at the beginning of each line and ; at the end
# Then eval all
eval "$(grep -E '^[A-Za-z_][A-Za-z0-9_]*=.*' '.env' | sed 's/.*/export &;/')"
#====================================================================================
# Archive
#====================================================================================
# Simple (Works for most cases)
export $(grep -v '^#' .env | xargs)
# Complex (Works with vars that contain spaces
eval "$(cat '.env' | grep -v '^#' | grep -v '^$' | sed 's/.*/export &;/')"
# Complex with 1 grep regex that covers all cases (comments, empty lines & validates the <var_name=...> style)
eval "$(cat './.env.local' | grep -E '^[A-Za-z_][A-Za-z0-9_]*=.*' | sed 's/.*/export &;/')"
#====================================================================================
# Example .env file
VAR=something
VAR2='one two three'
# Export all variables from a env var file
# $1 => env var file path
source_env_var_file() {
file="$1"
if [ ! -f "$file" ]; then
echo "Error: $file does not exist"
return 1
fi
while IFS= read -r line; do
# Trim whitespace from start and end of line
line=$(echo "$line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
# Validate the line against the regex (skips empty lines and comments and lines where key is not valid)
[[ ! "$line" =~ ^[A-Za-z_][A-Za-z0-9_]*=.* ]] && continue
# # Skip empty lines
# [ -z "$line" ] && continue
# # Skip comments
# [[ "$line" =~ ^#.*$ ]] && continue
# Split the line into a key and value
key=$(echo "$line" | cut -d "=" -f 1)
value=$(echo "$line" | cut -d "=" -f 2-)
# Trim whitespace from start and end of value
value=$(echo "$value" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
# Skip if the key or value is empty
[ -z "$key" ] || [ -z "$value" ] && continue
# If the value isn't wrapped in quotes and contains any special characters, wrap it in single quotes
if [[ "$value" != "'"* && "$value" != '"'* ]] && [[ "$value" =~ [[:space:]\!\@\#\$\%\^\&\*\(\)\[\]\{\}\<\>\?\!\~\`\:\;\+\=\-\.\/\\\|] ]]; then
value="'$value'"
fi
# Export the variable
export "$key"="$value"
done <"$file"
# # eval "$(grep -E '^export [A-Za-z_][A-Za-z0-9_]*=.*' "$file")" # validates lines with regex as (export key=value) and evals the line
# eval "$(grep -E '^[A-Za-z_][A-Za-z0-9_]*=.*' "$file" | sed 's/.*/export &;/')" # normal approach - validate lines with regex as (key=value) and export them
# Special chars to check: \s,!,@,#,$,%,^,&,*,(,),[,],{,},<,>,?,!,~,`,",',:,;,+,=,-,.,_,/,\,|
# Wrap the value in single quotes if contains special chars and not already wrapped
# eval "$(grep -E '^[A-Za-z_][A-Za-z0-9_]*=.*' "$file" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/[^A-Za-z0-9_]=/=/; s/.*/&;/; s/=[^'"'"'A-Za-z0-9_]/='\''&'\''/')"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment