who_need_help/scripts/set-env-values.sh

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"