2

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

このスクリプトには 2 つの問題があります。

  1. pgtest1.sh: 17: 構文エラー: 予期しないファイルの終わり (「完了」を期待)

  2. SQL で動的に $x を渡す方法

繰り返しごとに新しいデータベース接続を作成したい。

私はpostgreとshellの両方が初めてです。

ありがとう

プリヤンク

4

3 に答える 3

3

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
于 2012-05-18T09:14:28.540 に答える
0

EOF指定した方法はインデントできません。次のことを行う必要があります (ヒアドキュメントトークンの前のダッシュに注意してください:

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
于 2012-05-19T04:23:15.017 に答える
0

私の場合を除いて、それはmysql用です。私はzshを使用しています。エイリアスを設定して、スクリプトを呼び出したときにシェルがグロビングを実行しないようにして、これを実行できるようにします。

$ 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'"

シェルスクリプトに引用符を自動的に追加させたくない場合は、次のように = 演算子の前後のスペースを省略します。

$ sql select t1.col1,t2.col2 from Table1 t1 join Table t2 on t1.client_id=t2.client_id.

あなたがそれから利益を得るかもしれない場合に備えて、私はここにスクリプトを貼り付けています. これは zsh であり、mysql 固有です。psql で実行する sql コマンドを渡す方法に合わせて変更する必要があります。スクリプトで使用されるmpagerプログラムは、vim を呼び出して、表形式の出力を参照するのに適したページャーのように動作するように要求する別のシェル スクリプトです。

#!/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
于 2012-05-19T07:20:02.867 に答える