在 shell 中为 postgresql 转义单引号

3

我正在尝试在postgres帐户下通过psql执行SQL。我能够运行不包含引号的SQL。

root@server:/home/rosta/SCRIPTS# su postgres -c "psql -c 'SELECT NOW()'"
              now
-------------------------------
2014-06-07 09:38:17.120368+02
(1 row)

当SQL查询包含引号时,例如SELECT 'hi',就会出现问题。我正在测试简单的'hi',但我想从shell脚本中执行类似于这样的操作。

su postgres -c "psql -c 'create database $DB_NAME template=template0 encoding='utf8' owner=aaa lc_collate='cs_CZ.utf8''"

请问有人能告诉我如何在上述命令中避免编码和排序周围的引号吗?

以下是我的一些测试:

root@server:/home/rosta/SCRIPTS# su postgres -c "psql -c 'SELECT \'hi\''"
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
root@server:/home/rosta/SCRIPTS# su postgres -c "psql -c 'SELECT \\'hi\\''"
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
root@server:/home/rosta/SCRIPTS# su postgres -c 'psql -c \'SELECT \\'hi\\'\''

1
你可以尝试一下“倾斜牙签综合症”。为什么不直接留在根账户呢?根账户允许运行psql。 - jjanes
2个回答

6

我通常会使用双引号(")作为postgres -c的参数,用转义双引号(\")作为psql -c的参数。这样,我就可以在SQL字符串中自由地使用单引号('),而不会出现问题:

[root@mycomputer ~]# su postgres -c "psql -c \"SELECT 'hi'  \" "
 ?column? 
----------
 hi
(1 row)

为什么会被踩票?能否请踩票者解释一下原因? - Mureinik
1
简而言之,从安全角度来看,这是非常危险的--它不仅允许 SQL 注入,还允许 shell 注入,如果有人尝试在不知道其内容的情况下通过这种方式插入变量。也就是说,我要假设为了使这在实际中有用,则应为 SELECT '${greeting}',但是如果 greeting=$(rm -rf ~) 或者更邪恶的同类 greeting=$'\'$(rm -rf ~)\'$(rm -rf ~)',那么 postgresql 帐户的主目录就处于风险之中。 - Charles Duffy

4

最简单的方法是使用“here文档”,它忽略所有引用:

#!/bin/sh
DB_NAME=my_data_base

psql -U postgres postgres <<STOP_IT
create database $DB_NAME template=template0
  encoding='utf8'
  owner=aaa
  lc_collate='cs_CZ.utf8'
  ;
STOP_IT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接