本地通过SSH执行远程PostgreSQL查询时出现语法错误问题
解决SSH远程执行PostgreSQL查询的语法错误问题
我一看你这个报错就知道是引号转义搞的鬼!问题出在你通过SSH传递psql命令的时候,本地Shell会先解析一部分特殊字符,传到远程机器后,查询语句的语法结构就被拆乱了,导致bash报出syntax error near unexpected token '('的错误。
给你两种简单的修复方案,选一种就行:
方案一:转义查询语句里的单引号
把原来的命令替换成下面这样,核心是用两个连续的单引号''来转义查询里的单引号,同时用$()代替反引号(更现代的写法,可读性更强):
query=$(ssh -i "$PKEY" "$REMOTE" "$PGBIN/psql -U $PGUSER -h $PGHOST -p $PGPORT -d $PGDATABASE -Atc 'select datname from pg_database where datname not in (''template0'',''template1'');'") echo "$query"
方案二:用双引号包裹查询语句
另一种思路是把psql的-c参数内容用双引号包裹,同时转义本地Shell的双引号,让远程Shell能正确识别:
query=$(ssh -i "$PKEY" "$REMOTE" "$PGBIN/psql -U $PGUSER -h $PGHOST -p $PGPORT -d $PGDATABASE -Atc \"select datname from pg_database where datname not in ('template0','template1');\") echo "$query"
完整修改后的脚本
这里给你整理好完整的脚本,还顺便给变量加了双引号(避免路径或用户名含空格时出问题):
#!/bin/bash REMOTE="postgres@192.168.1.200" PKEY="/home/postgres/pr-key.ppk" SCRIPT_LOCATION="/home/postgres/scripts" CRONLOG_LOCATION="/home/postgres/project/cronlogs" PGBIN="/usr/pgsql-9.6/bin" PGUSER="postgres" PGDATA="/opt/PostgreSQL/9.6/data" PGDATABASE="postgres" PGPORT="5432" PGHOST="192.168.1.200" BLOG="/home/postgres/blogfile" query=$(ssh -i "$PKEY" "$REMOTE" "$PGBIN/psql -U $PGUSER -h $PGHOST -p $PGPORT -d $PGDATABASE -Atc 'select datname from pg_database where datname not in (''template0'',''template1'');'") echo "$query"
原理很简单:当通过SSH执行远程命令时,必须确保查询语句里的特殊字符(括号、引号)能完整传递到远程Shell,不会被本地Shell提前解析。用单引号转义或者双引号包裹的方式,就能让远程的bash正确识别整个PostgreSQL查询语句。
内容的提问来源于stack exchange,提问作者Siva Krishna
相关产品推荐
相关产品推荐

