如何修复bash脚本未完成Postgres命令

时间:2019-01-24 05:43:42

标签: linux bash postgresql

脚本仅打开Postgres,但此后不处理任何命令。

#/bin/bash
filename='mac_addresses.txt'
filelines=`cat $filename`
echo Start
for line in $filelines ; do
    psql pcoip_mc_db postgres
    update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
    \q
done

预期结果是看到此脚本在mac_addresses.txt文件中逐行移动,并连接到Postgres之后,在mac_addresses.txt中的每个mac地址上运行此命令:

update endpoint set endpoint_group_id = 15 where mac_address='$filelines';

2 个答案:

答案 0 :(得分:0)

这3行没有达到您的期望:

psql pcoip_mc_db postgres
update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
\q

每行应为bash命令。因此,您需要将SQL查询包装在字符串中,然后将其传递给psql命令。像这样:

psql pcoip_mc_db postgres -c "update endpoint set endpoint_group_id = 15 where mac_address='$line';"

({-c告诉psql将字符串作为SQL命令执行)

此外,当您要为文件的每一行连接数据库或从数据库断开连接时,此bash的效率将有所降低。更加惯用的bash脚本会将文件的每一行转换为适当的SQL表达式,然后将所有生成的SQL通过管道传递到单个psql连接中。这可以用一行替换脚本:

<"$filename" awk '{print "update endpoint set endpoint_group_id = 15 where mac_address=\'"'"'"$0"\'"'"';"}' | psql pcoip_mc_db postgres

(作为进一步的改进,您甚至可以使用IN子句生成单个SQL查询,例如:update endpoint set endpoint_group_id = 15 where mac_address IN ('mac1', 'mac2', ...);

答案 1 :(得分:0)

问题在于update\q不是作为psql命令的输入而是作为Shell命令处理的。您必须告诉bash,这应该是psql的标准输入,例如使用“ here document”:

#/bin/bash
filename='mac_addresses.txt'
filelines=`cat $filename`
echo Start
for line in $filelines ; do
    psql pcoip_mc_db postgres <<EOF
    update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
EOF
done

警告:此代码仍然不安全,并且容易受到SQL注入的攻击。如果文件中的任何条目包含空格或单引号,您将得到错误,甚至更糟。