Bash安全地从文件中获取变量
我有一个脚本,它将变量存储在一个.txt文件中供以后使用。我想安全地从文件中检索这些变量 我现在是如何设置的: Settings.txtBash安全地从文件中获取变量,bash,parsing,variable-assignment,Bash,Parsing,Variable Assignment,我有一个脚本,它将变量存储在一个.txt文件中供以后使用。我想安全地从文件中检索这些变量 我现在是如何设置的: Settings.txt var1=value1 var2=value2 ... 剧本 for i in $(cat Settings.txt); do $i done # So now "var1" has the value "value1", and so on 这是可行的,但很危险,因为有人可能会通过txt文件注入代码 我知道source命令,但它也有同样的问题。那么,如何
var1=value1
var2=value2
...
剧本
for i in $(cat Settings.txt); do $i done
# So now "var1" has the value "value1", and so on
这是可行的,但很危险,因为有人可能会通过txt文件注入代码
我知道
source
命令,但它也有同样的问题。那么,如何安全地实现相同的功能?您可以在寻源之前检查变量分配格式:
#!/bin/bash
file=Settings.txt
regex_varname='^[a-zA-Z0-9_]\+\'
regex_varvalue='[a-zA-Z0-9]\+$'
is_safe_var() {
while read var; do
grep -q $regex_varname=$regex_varvalue <<< "$var" || return 1
done < "$file"
}
is_safe_var && source "$file" || echo "Break"
#/bin/bash
file=Settings.txt
regex_varname='^[a-zA-Z0-9\+\'
regex_varvalue='[a-zA-Z0-9]\+$'
_安全吗_var(){
读var时;做
grep-q$regex\u varname=$regex\u varvalue如果您不想为验证和变量创建单独的步骤:
更新,基于declare
:一种仍然安全的更简单方法是使用declare
内置来定义变量:
#!/usr/bin/env bash
# Read the file line by line.
while read -r line; do
declare -- "$line"
done <<'EOF'
var1=value1
var2=value2
EOF
- 请注意,这些值是以文本形式读取的,与文件中的定义完全相同(除去尾随空格除外)
- 如果存在单引号或双引号的值,并且要删除引号,请使用以下
printf-v
命令:
printf-v“${BASH_重新匹配[1]}”%s“$(xargs-I{}printf%s{}”你说的安全
?停止任何代码的执行是什么意思?@sobolevn是的,我不希望任何代码会意外地从txt文件中被执行。如果文件中有rm-fr/
这一行,它会造成一些不必要的损害:/@BonBon:变量总是以var
开头吗?@sjsam不,它们可以是任何变量name包含大小写字符和一个“\ux”。值可以是1、0或一些没有特殊字符的短字符串。谢谢你的回答!你能解释一下正则表达式的作用吗?因为它有点难理解。@bonbonbon:很高兴听到这个消息;我刚刚想到使用声明而不是printf-v
允许使用更简单的解决方案;请查看我的更新。
#!/usr/bin/env bash
# Read the file line by line.
while read -r line; do
# Split the line into name and value using regex matching.
if [[ $line =~ ^([^=]+)=(.*)$ ]]; then
# ${BASH_REMATCH[1]} now contains the variable name,
# ${BASH_REMATCH[2]} the value.
# Use printf -v to store the value in a variable.
printf -v "${BASH_REMATCH[1]}" %s "${BASH_REMATCH[2]}"
fi
done <<'EOF'
var1=value1
var2=value2
EOF
# Print the variables that were created (based on name prefix `var`).
for name in ${!var*}; do
printf '%s=%s\n' "$name" "${!name}"
done