shell脚本接收含$的命令行密码参数被解析如何获取原始值
问题根因
你观察到的$$被替换为PID、$1等特殊标识符被解析的现象,并非发生在pass=$2赋值阶段,而是代码里eval set -- "$TEMP"这行触发了shell的变量展开逻辑,密码里的$开头符号就是在这一步被篡改的。
解决方案
1. 代码修改(兼容长选项,替换不安全的eval逻辑)
用declare数组解析getopt的输出,替代eval避免触发不必要的变量解析,修改后代码如下:
# Input TEMP=$(getopt -o ap: --long admin:,pass: -n 'add-vhost' -- "$@") if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # 替换原来的eval行,用数组安全解析不会触发变量展开 declare -a args="($TEMP)" set -- "${args[@]}" while true; do case "$1" in -a | --admin ) admin="$2"; shift 2 ;; -p | --pass ) pass="$2"; shift 2 ;; -- ) shift; break ;; * ) exit; break ;; esac done # 输出时添加双引号避免二次解析 echo "$admin" echo "$pass"
2. 调用端注意事项
脚本层面的修改仅能避免脚本内部解析时篡改参数,用户在命令行调用脚本时,必须用单引号包裹包含$/!/空格等特殊字符的参数,否则父shell会在脚本启动前就完成特殊符号解析,脚本无法拿到原始输入。
正确调用示例:./add-vhost --admin test --pass 'Test$$123'
可选方案(无需长选项时)
如果不需要使用长选项,可以直接使用bash内置的getopts处理参数,该工具不需要调用外部getopt和eval逻辑,天然不会触发变量解析问题,安全性更高。
内容的提问来源于stack exchange,提问作者o'gamingSCV
相关产品推荐
相关产品推荐

