100 lines
1.9 KiB
Bash
Executable File
100 lines
1.9 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
if [ "$#" -ne 2 ]; then
|
|
echo "Usage: $0 ENV_FILE VALUES_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
env_file=$1
|
|
values_file=$2
|
|
|
|
if [ ! -f "$env_file" ]; then
|
|
echo "Environment file does not exist: $env_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$values_file" ]; then
|
|
echo "Values file does not exist: $values_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(stat -c '%a' "$env_file")" != 600 ]; then
|
|
echo "Environment file must have mode 0600: $env_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
case "$(stat -c '%a' "$values_file")" in
|
|
400|600) ;;
|
|
*)
|
|
echo "Values file must have mode 0400 or 0600: $values_file" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
env_dir=$(CDPATH='' cd -- "$(dirname -- "$env_file")" && pwd)
|
|
env_name=$(basename -- "$env_file")
|
|
temporary_env=$(mktemp "$env_dir/$env_name.tmp.XXXXXX")
|
|
trap 'rm -f "$temporary_env"' EXIT HUP INT TERM
|
|
chmod 600 "$temporary_env"
|
|
|
|
if ! awk '
|
|
BEGIN {
|
|
FS = "="
|
|
reading_values = 1
|
|
}
|
|
|
|
FNR == 1 && NR != 1 {
|
|
reading_values = 0
|
|
}
|
|
|
|
reading_values {
|
|
key = $1
|
|
|
|
if (key !~ /^[A-Z][A-Z0-9_]*$/ || key in replacement) {
|
|
exit 40
|
|
}
|
|
|
|
value = substr($0, index($0, "=") + 1)
|
|
gsub(/\$/, "$$", value)
|
|
replacement[key] = value
|
|
replacement_count++
|
|
next
|
|
}
|
|
|
|
{
|
|
separator = index($0, "=")
|
|
|
|
if (separator > 1) {
|
|
key = substr($0, 1, separator - 1)
|
|
|
|
if (key in replacement) {
|
|
seen[key]++
|
|
print key "=" replacement[key]
|
|
next
|
|
}
|
|
}
|
|
|
|
print
|
|
}
|
|
|
|
END {
|
|
if (replacement_count == 0) {
|
|
exit 41
|
|
}
|
|
|
|
for (key in replacement) {
|
|
if (seen[key] != 1) {
|
|
exit 42
|
|
}
|
|
}
|
|
}
|
|
' "$values_file" "$env_file" >"$temporary_env"; then
|
|
echo "Refusing to update the environment: values must use unique KEY=VALUE lines and every key must already occur exactly once." >&2
|
|
exit 1
|
|
fi
|
|
|
|
mv "$temporary_env" "$env_file"
|
|
trap - EXIT HUP INT TERM
|
|
echo "Environment values updated without printing their contents: $env_file"
|