在Bash脚本中,eval
、变量和引号的组合使用是一个常见但容易出错的场景。以下是完整的解析:
eval
命令:将字符串作为Bash命令执行(先展开变量/转义字符,再执行结果)。$var
替换为实际值)。"
:允许变量扩展,但保护特殊字符(如空格、*
)不被Shell解析。'
:禁止所有扩展,内容原样输出。var="hello world"
cmd="echo $var" # 直接展开变量,相当于 cmd="echo hello world"
eval $cmd # 执行后输出 "hello world",但若$var含特殊字符(如`; rm -rf /`)会引发安全问题。
原因:变量在赋值时已被展开,若内容含特殊字符会被Shell解析为命令。
var="hello world"
cmd="echo \"$var\"" # cmd值为 echo "hello world"
eval $cmd # 报错:world"未找到命令
原因:eval $cmd
会先拆分为eval
、echo "hello
、world"
,引号失去保护作用。
var="hello; rm -rf /" # 恶意输入示例
cmd="echo \"$var\"" # cmd值为 echo "hello; rm -rf /"
eval "$cmd" # 输出:hello; rm -rf /(安全,内容作为字符串处理)
关键:eval "$cmd"
中的双引号保证$cmd
作为整体传递,避免分拆。
var="hello world"
cmd=(echo "$var") # 数组自动处理空格和引号
eval "${cmd[@]}" # 安全执行
printf %q
转义特殊字符var="hello; rm -rf /"
printf -v escaped_var "%q" "$var" # 转义特殊字符
eval "echo $escaped_var" # 输出原内容,安全执行
eval
执行未过滤的输入可能导致命令注入。bash -c
传递命令。eval
# 安全地通过变量名间接获取值
name="USERNAME"
value="USERNAME"
eval echo \$$name # 输出当前用户名(需转义$)
通过理解Bash的展开顺序和引号作用,可以避免大多数eval
相关的问题。
没有搜到相关的沙龙