You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本执行pgloader时变量未替换及索引错误问题

问题分析与解决

问题根源

  1. 密码变量解析错误:pgsql_password="Test%%*$"中的$是Bash特殊字符,会被当作变量引用,实际传递给urlencode的密码为空,导致输出的连接串缺失密码部分,同时触发Python的IndexError: list index out of range(因为sys.argv[1]不存在)。
  2. 不必要的URL编码:对数据库地址(如test_pg_url.rds.amazonaws.com:5432)进行URL编码是错误的,pgloader的连接串中主机和端口无需编码,编码后会导致无法识别正确的连接地址。
  3. eval命令的风险:拼接命令字符串后用eval执行,容易引发特殊字符解析错误,且存在安全隐患。

修复方案

  • 用单引号包裹密码变量,避免Bash解析特殊字符;
  • 仅对密码进行URL编码,主机地址和端口直接使用原始值;
  • 改进URL编码函数,通过stdin传递参数,规避Bash参数解析问题;
  • 直接调用pgloader命令,无需拼接字符串和eval。

修改后的脚本

#!/bin/bash
# Function to URL encode a string via stdin
urlencode() {
  python3 -c "import sys, urllib.parse as ul; print(ul.quote(sys.stdin.read().strip()))"
}

# MySQL connection string
mysql_password='Tes^((***))'
mysql_encoded_pass=$(echo "$mysql_password" | urlencode)
mysql_connection="mysql://mysqluser:$mysql_encoded_pass@test_mysql_url.rds.amazonaws.com:3306/db_af"

# PostgreSQL connection string
pgsql_password='Test%%*$'
pgsql_encoded_pass=$(echo "$pgsql_password" | urlencode)
pgsql_connection="pgsql://pguser:$pgsql_encoded_pass@test_pg_url.rds.amazonaws.com:5432/db_dev"

echo $pgsql_connection

# Execute pgloader directly
pgloader "$mysql_connection" "$pgsql_connection"

关键修改说明

  1. 密码变量用单引号:mysql_password='Tes^((***))'和pgsql_password='Test%%*$',确保所有特殊字符被当作普通字符处理;
  2. URL编码函数改进:通过stdin传递密码,避免Bash对参数的解析干扰,同时Python代码读取stdin,无需依赖sys.argv[1],防止IndexError;
  3. 移除地址的URL编码:直接使用原始主机地址和端口,保证pgloader能正确识别连接地址;
  4. 直接调用pgloader:将连接串作为参数直接传递,避免eval带来的解析问题和安全风险。

内容的提问来源于stack exchange,提问作者Prem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:52:42