web-dev-qa-db-ja.com

PostgreSQL-データベースユーザー「postgres」としてのbashスクリプトからのクエリ

PostgreSQLデータベースに、c_uidc_defaultsc_settingsの3つの列があるテーブルがあります。 c_uidは単にユーザーの名前を保存するだけで、c_defaultsはそのユーザーに関する多くのデータを含む長いテキストです。

c_defaults値に基づいてc_uid列の値を選択するbashスクリプトからステートメントを実行する必要がありますが、これはデータベースユーザー「postgres」が行う必要があります。

CLIでは、次のことができます。

[mymachine]# su postgres
bash-4.1$psql
postgres=#\c database_name
You are now connected to database "database_name" as user "postgres".
database_name=#SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser';

ただし、bashスクリプトを使用してこれを実現するにはどうすればよいですか?

目的は、その列から情報を取得し、編集して、その列に書き戻すことです(すべてbashスクリプトを使用)。

40
rahuL

これを試してください:

#!/bin/bash
psql -U postgres -d database_name -c "SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'"

またはsuを使用:

#!/bin/bash
su -c "psql -d database_name -c \"SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'\"" postgres

また、Sudo

#!/bin/bash
Sudo -u postgres -H -- psql -d database_name -c "SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'"
88
konsolebox

以下のようにpsqlに接続し、ブロック内の通常のpostgres関数で行うようにsqlクエリを作成できます。そこでは、bash変数を使用できます。ただし、#の代わりに使用する必要があるコメントであっても、スクリプトは厳密にsqlにする必要があります。

#!/bin/bash
psql postgresql://<user>:<password>@<Host>/<db> << EOF
       <your sql queries go here>
EOF
20
picmate 涅

別のsqlファイルから実行する場合。ここに良い例があります(postgresqlでbashする方法を学ぶための素晴らしいページから引用) http://www.manniwood.com/postgresql_and_bash_stuff/index.html

#!/bin/bash
set -e
set -u
if [ $# != 2 ]; then
   echo "please enter a db Host and a table suffix"
   exit 1
fi

export DBHOST=$1
export TSUFF=$2
psql \
  -X \
  -U user \
  -h $DBHOST \
  -f /path/to/sql/file.sql \
  --echo-all \
  --set AUTOCOMMIT=off \
  --set ON_ERROR_STOP=on \
  --set TSUFF=$TSUFF \
  --set QTSTUFF=\'$TSUFF\' \
   mydatabase

   psql_exit_status = $?

   if [ $psql_exit_status != 0 ]; then
     echo "psql failed while trying to run this sql script" 1>&2
     exit $psql_exit_status
   fi

   echo "sql script successful"
exit 0
13
shacharsol

postgresとしてログインしたら、次のように書くことができます。

psql -t -d database_name -c $'SELECT c_defaults FROM user_info WHERE c_uid = \'testuser\';'

そのフィールドの値のみを出力します。つまり、その値をキャプチャして(たとえば)Bash変数に保存できます。

testuser_defaults="$(psql -t -d database_name -c $'SELECT c_defaults FROM user_info WHERE c_uid = \'testuser\';')"

ログインをpostgresとして処理するには、Sudoを使用することをお勧めします。特定のユーザーに実行許可を与えることができます

Sudo -u postgres /path/to/this/script.sh

postgresとして1つのスクリプトだけを実行できるようにします。

8
ruakh

スクリプトでpsqlにコマンドを渡す最も安全な方法は、文字列をパイプするか、here-docを渡すことです。

-c/--commandオプションのマニュアルドキュメントは、回避すべき場合にさらに詳細に説明します。

   -c command
   --command=command
       Specifies that psql is to execute one command string, command, and then exit. This is useful in Shell scripts. Start-up files (psqlrc and ~/.psqlrc)
       are ignored with this option.

       command must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features), or a single
       backslash command. Thus you cannot mix SQL and psql meta-commands with this option. To achieve that, you could pipe the string into psql, for
       example: echo '\x \\ SELECT * FROM foo;' | psql. (\\ is the separator meta-command.)

       If the command string contains multiple SQL commands, they are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands
       included in the string to divide it into multiple transactions. This is different from the behavior when the same string is fed to psql's standard
       input. Also, only the result of the last SQL command is returned.

       Because of these legacy behaviors, putting more than one command in the -c string often has unexpected results. It's better to feed multiple
       commands to psql's standard input, either using echo as illustrated above, or via a Shell here-document, for example:

           psql <<EOF
           \x
           SELECT * FROM foo;
           EOF
2
Dennis

@Jasonの質問に答えるには、私のbashスクリプトで、(私の目的のために)次のようなドームを作りました:

dbPass='xxxxxxxx'
.....
## Connect to the DB
PGPASSWORD=${dbPass} psql -h ${dbHost} -U ${myUsr} -d ${myRdb} -P pager=on --set AUTOCOMMIT=off

別の方法は次のとおりです。

psql --set AUTOCOMMIT=off --set ON_ERROR_STOP=on -P pager=on \
     postgresql://${myUsr}:${dbPass}@${dbHost}/${myRdb}

ただし、パスワードについては十分に注意する必要があります。そのように機能するために、':を使用してパスワードを作成できませんでした。結局、あきらめました。

-S

0
MacUsers