如何向bash脚本的PostgreSQL psql重命名数据库命令传递bash变量
问题原因
你推测的结论完全正确,问题根源是Bash的字符串解析规则:单引号包裹的所有内容会被当做纯文本处理,不会执行变量展开、命令替换等操作,因此你写的$O_Name、$N_Name会直接作为字符串传入SQL,自然无法匹配到对应的数据库。
可行解决方法
下面按推荐优先级给出三种解决方案:
方案1:使用psql原生变量传递(最推荐)
psql自带-v参数用于向会话内传递自定义变量,会自动处理标识符的转义逻辑,就算库名包含特殊字符、大小写也不会出错,同时能避免SQL注入风险:
O_Name='Old_Name' N_Name='New_Name' psql -U $User -t -A -q \ -v old_db="$O_Name" \ -v new_db="$N_Name" \ -c 'ALTER DATABASE :"old_db" RENAME TO :"new_db"'
SQL中使用:"变量名"的格式调用传入的变量,psql会自动给值加上双引号作为标识符包裹符。
方案2:外层改用双引号包裹SQL语句
将-c参数后的内容外层改为双引号,Bash就会自动展开内部的变量,只需要把SQL需要的内部双引号用反斜杠转义即可:
psql -U $User -t -A -q -c "ALTER DATABASE \"$O_Name\" RENAME TO \"$N_Name\""
方案3:单引号拆分拼接
如果不想大量转义双引号,也可以拆分单引号做字符串拼接,将变量部分用双引号包裹保证展开:
psql -U $User -t -A -q -c 'ALTER DATABASE "'"$O_Name"'" RENAME TO "'"$N_Name"'"'
这个写法的逻辑是:先结束前半段SQL的单引号,接着用双引号包裹变量保证变量正常展开,再开启单引号续上后半段SQL。
内容的提问来源于stack exchange,提问作者Tsunani
相关产品推荐
相关产品推荐

