我想为我正在处理的 zsh shell 脚本存储一些默认变量。我知道source
在我的脚本中使用一行是可行的,但不是最安全的方法。
为了确保所有用户的最大兼容性,有没有办法使用 zsh(在 Amazon Linux 2 上,具体情况)中默认提供的工具来安全地从文本文件中读取行并从配置文件中提取一组预设变量?
虽然我知道文本文件本身不会被散列,但这不是我的问题。我的目标只是避免有人将恶意代码插入配置文件并由脚本处理的可能性。
答案1
除了 zsh 提供的字符串处理设施之外,我想不出 zsh 中还有任何功能可以促进这一点参数扩展。
下面是一些代码,它将 KEY=VALUE 行解析为关联数组,config
并具有以下约束:
- 键只能包含 ASCII 字母、数字和下划线。键不能以数字开头,也不能为空。
- 值可以包含除换行符和空字节之外的任何字节字符串。请注意,这可能包括多字节编码(例如 UTF-8)中的无效序列。
- 空白行(仅包含 ASCII 水平空白的行)和注释行(以空白和 a 开头的行
#
)将被忽略。 - 没有任何类型的扩展:没有变量替换,没有引用,没有空格消除。
function parse_config {
emulate -LR zsh
setopt extended_glob
local n=0 line lines
local LC_ALL=C
lines=("${(@f)$(<$1)}")
for line in "${(@)lines}"; do
((++n))
line=${line##[$' \t']##}
if [[ -z $line || $line == \#* ]]; then
continue
elif [[ $line = *$'\0'* ]]; then
echo >&2 "$1:$n:Null character in configuration file"
config=()
return 1
elif [[ $line == [A-Z_a-z][0-9A-Z_a-z]#\=* ]]; then
config[${line%%=*}]=${line#*=}
else
echo >&2 "$1:$n:Syntax error in configuration file"
config=()
return 1
fi
done
}
调用该函数:
set -e
typeset -A config
parse_config /path/to/config/file
echo "Configuration dump:"
for k in ${(ko)config}; do
print -lr "$k=$config[$k]"
done