PGAdmin正常执行的PostgreSQL更新语句在终端/Shell脚本中异常
问题根源
你的问题核心是Shell会将双引号字符串中的$符号解析为变量引用。密码哈希中的$2a$12$...被Shell错误处理:$2会被当作第二个位置参数(当前无参数时为空),后续的a保留,剩下的$...部分同样被解析为空,最终传入PostgreSQL的字符串只剩a,导致数据库字段被错误设置。
而PGAdmin中执行正常,是因为PGAdmin的SQL编辑器不会像Shell那样解析$符号,会直接将完整的哈希字符串传递给PostgreSQL。
解决方案
以下三种方法都可以解决这个问题,按推荐程度排序:
方法一:使用psql变量替换(最安全)
通过-v参数定义psql内部变量,避免Shell解析特殊字符,同时提升代码可读性和安全性:
psql -U postgres -h (sample-host) (sample-db) -p (sample-port) \ -v password_hash='$2a$12$ohJ0j2Y9lRkO6Ld9MaiLuu7Q4hzYSr1IsM5SfY1SxAGk6fgn20aj2' \ -v target_email='email@email.com' \ -c 'UPDATE web_user SET password_hash = :password_hash WHERE email = :target_email'
方法二:用单引号包裹整个SQL命令
Shell单引号内的内容会被原样保留,不会解析$变量。注意SQL中的单引号需要写成两个连续单引号(PostgreSQL的单引号转义规则):
psql -U postgres -h (sample-host) (sample-db) -p (sample-port) -c 'UPDATE web_user SET password_hash = ''$2a$12$ohJ0j2Y9lRkO6Ld9MaiLuu7Q4hzYSr1IsM5SfY1SxAGk6fgn20aj2'' WHERE email = ''email@email.com'''
方法三:转义双引号内的$符号
在双引号字符串中,给每个$添加反斜杠\,让Shell将其当作普通字符处理:
psql -U postgres -h (sample-host) (sample-db) -p (sample-port) -c "UPDATE web_user SET password_hash = '\$2a\$12\$ohJ0j2Y9lRkO6Ld9MaiLuu7Q4hzYSr1IsM5SfY1SxAGk6fgn20aj2' WHERE email = 'email@email.com'"
内容的提问来源于stack exchange,提问作者JB Omega
相关产品推荐
相关产品推荐

