这与PostgreSQL无关。这是一个shell引用问题。
你不能在bash中嵌套单引号。所以这个:
'insert into ftp_mgr (id, info) values("192.168.1.12", '{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}');'
被读到:
'insert ...'{
和{
是*不带引号的字符串的一部分。因此,shell试图将{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}
解释为shell命令。
在这里做最简单的就是用一个带引号的here文档,以避免需要处理'
字面报价与外壳的引用混合:各地这里 -
psql -t -d mydb <<'__END__'
insert into ftp_mgr (id, info) values
("192.168.1.12", '{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}');
__END__
的报价文件标签是重要。如果将它们排除在外,bash仍会查找并替换$variable
字符串等。这可以非常方便,但在这种情况下显然不是你想要的。
如果您必须使用-c
做到这一点,你有两个选择:
使用shell的字符串连接。无论何时你想要一个单引号,结束当前单引号字符串,写"'"
,并打开一个新的单引号字符串。所以你会写:
'insert ... values(..., '"'"'{"....
混淆阅读,不是吗?第一个'
结束单引号外壳字符串。然后"'"
是一个单引号,用shell引用的双引号引用。然后下一个'
开始一个新的单引号字符串。
这是可怕的阅读,而且它也不遑多让写为:
'insert ... values(..., '\''{"....
所以个人,当我需要一个参数字符串中的单引号,我不是双引号将整个字符串和反斜杠转义shell字符:
"insert into ftp_mgr (id, info) values(\"192.168.1.12\", '{\"username\": \"Administrator\", \"password\": \"abc456\$\", \"serverAddr\":\"192.168.1.12\"}');"
......或者在可能的情况下,我使用引用此处的文档来解决整个可怕的混乱。
我的首选是避免使用这种类型的shell并使用简单的Python脚本。
import psycopg2
conn = psycopg2.connect('dbname=postgres')
curs = conn.cursor()
curs.execute(r'insert into ftp_mgr (id, info) values(%s, %s);', (
r'192.168.1.12',
r'{"username": "Administrator", "password": "abc456$", "serverAddr":"192.168.1.12"}'
))
Python对原始字符串(r''
),三引号字符串("""
)等的支持,使得这类事情要容易得多。