在Bash脚本中使用psql的-c参数创建数据库遇到问题
解决psql -c参数执行CREATE DATABASE命令的问题
核心错误分析
你之前的写法失败主要有两个关键问题:
- 连接目标错误:创建数据库时,不能连接到待创建的
${DATABASE}(它还不存在),必须连接到已存在的默认库(如postgres或template1)。 - 参数格式错误:
-c后面的SQL命令必须作为单个字符串参数传递给psql,你尝试的转义引号、大括号/括号包裹都是不符合shell语法的错误写法。
正确写法示例
写法1:双引号包裹SQL(支持shell变量替换)
这是最常用的方式,适合脚本中需要替换${HOST}/${USER}/${DATABASE}变量的场景:
psql -w -h "${HOST}" -U "${USER}" postgres -c "CREATE DATABASE ${DATABASE} WITH OWNER = ${USER} ENCODING = 'UTF8' CONNECTION LIMIT = -1 IS_TEMPLATE = False;"
- 给变量
${HOST}/${USER}也加上双引号,避免变量值包含空格时出现解析错误。 - 连接目标用
postgres(默认存在的系统库),而非待创建的数据库。
写法2:用psql变量传递更安全(避免shell解析冲突)
如果担心shell变量和SQL语法冲突,可通过psql的-v参数传递变量,再在SQL中引用:
psql -w -h "${HOST}" -U "${USER}" postgres -v db_name="${DATABASE}" -v db_owner="${USER}" -c 'CREATE DATABASE :"db_name" WITH OWNER = :"db_owner" ENCODING = '\''UTF8'\'' CONNECTION LIMIT = -1 IS_TEMPLATE = False;'
- 单引号包裹SQL,避免shell解析内部内容;内部的单引号用
'\''转义。 - 用
:"变量名"的格式在SQL中引用psql变量,更安全可靠。
常见错误的原因
- 未加引号的SQL命令会被shell按空格分割成多个参数,psql无法识别完整的SQL语句。
- 使用
"是HTML转义字符,shell不识别,必须用实际的双引号"或单引号'。 - 双引号套双引号会导致shell解析混乱,需转义内部双引号(如
\"),但你的SQL用的是单引号,完全没必要这么做。 - 大括号/括号不是shell中包裹字符串的合法格式,
-c参数只接受字符串。
内容的提问来源于stack exchange,提问作者Andres Lorenzo Carvia
相关产品推荐
相关产品推荐

