我正在编写一个shell脚本来在postgres中运行一堆查询。
这是我写的脚本。
#!/bin/sh
host="172.16.7.102"
username="priyank"
dbname="truaxis"
x=1
echo "Connection done"
while [ $x -le 3 ]
do
x=$(($x + 1 ))
echo "Connection $x"
psql -h $host $dbname $username << EOF
select * from students where sid = $x;
EOF
done
此脚本存在两个问题。
pgtest1.sh:17:语法错误:文件结束意外(期待“完成”)
如何动态传递sql中的$ x
我想每次迭代创建新的数据库连接。
我是postgre和shell的新手。
由于
Priyank
答案 0 :(得分:1)
1)pgtest1.sh:17:语法错误:文件结束意外(期待“完成”)
你需要单独使用EOF(没有空格等)
psql -h $host $dbname $username << EOF
select * from students where sid = $x;
EOF
2)如何在动态sql中传递$ x
$ sh scriptname.sh value_of_x
然后在你的脚本中
x=$1
答案 1 :(得分:0)
EOF
您指定的方式无法缩进。您需要执行以下操作(请注意 here-doc标记之前的短划线:
while [ $x -le 3 ] ; do
psql foo bar <<-EOQ
select * from students where sid = $x;
EOQ
done
作为旁注,为什么不使用for
循环代替while
?
for (( x=$1 ; x<=3 ; x++ )) ; do
foo
done
答案 2 :(得分:0)
我做了同样的事情,除了我的情况,它是为mysql。我正在使用zsh。我设置了一个别名,以便在调用脚本时shell不会执行任何通配,以便我可以这样做:
$ sql select * from Table
而不是:
$ sql select '*' from Table
别名是:
alias sql='noglob sql'
我还使用sed
在必要时自动添加引号,以便我可以这样做:
$ sql select * from Client where first_name like John% and last_name = Wiley
而不是:
$ sql select '*' from Client where first_name like "'John%'" and last_name = "'Wiley'"
如果我不希望shell脚本自动添加引号,我会省略=运算符之前和之后的空格,如下所示:
$ sql select t1.col1,t2.col2 from Table1 t1 join Table t2 on t1.client_id=t2.client_id.
我在这里粘贴脚本,以防你可以从中获利。它是zsh,特定于mysql。您必须修改它以适应传递sql命令以在psql中运行的方式。脚本中使用的mpager
程序是另一个调用vim的shell脚本,并要求它像适合浏览表格输出的寻呼机一样:
#!/usr/bin/zsh
function usage() {
echo -n "Usage: $0 [-h] [-t] [-d db] [-q] [-v] [-n] [p] [-q] [sql commands]
-d db Use specified database instead of the default one
-t Do not 'tabularize' (borders) the output
-v Be verbose
-n Dry-run - show what command to be executed
-p Pipe output to mpager
-q Surpress own output, only show output from mysql
-h Show this help message
"
}
password=${DB_PASS:-secret}
db=${DB:-default_db}
user=${DB_USER:-username}
USE_TABLE='--table'
while getopts d:tvnhpq o
do
case "$o" in
d) db=$OPTARG ;;
t) USE_TABLE='' ;;
v) verbose=1 ;;
n) dry_run='echo' ;;
p) use_mpager=t ;;
h) usage; exit 0 ;;
q) quiet=1;;
*) usage;
exit 1 ;;
esac
done
shift `expr $OPTIND - 1`
case $2 in
database|databases)
db=
;;
esac
if [ -z "$quiet" -a -n "$db" ]; then
echo 1>&2 "Database: $db"
fi
if [ $# -lt 1 ]; then
mysql --table -u $user -p$password $db "$@"
exit
fi
to_run=`echo $*|sed -e "s/ \(=\|like\) *\([^'][^ ]*\+\)/ \1 '\2'/g"`
# This helps for debugging. Show what is going to run when output is going to a
# terminal:
if [ -t 1 ]; then
echo "to_run: $to_run" 1>&2
fi
if [ -n "$verbose" ]; then
echo "mysql $USE_TABLE -u $user -p$password $db -e ${(q)to_run}"
fi
if [ -n "$use_mpager" ]; then
$dry_run mysql $USE_TABLE -u $user -p$password $db -e "$to_run" | mpager
else
$dry_run mysql $USE_TABLE -u $user -p$password $db -e "$to_run"
fi