wake-up-neo.net

PostgreSQL - Abfrage vom Bash-Skript als Datenbankbenutzer "postgres"

In meiner PostgreSQL-Datenbank gibt es eine Tabelle mit 3 Spalten - c_uid, c_defaults und c_settings. c_uid speichert einfach den Namen eines Benutzers und c_defaults ist ein langer Text, der viele Daten enthält, die dieser Benutzer enthält.

Ich muss eine Anweisung aus einem Bash-Skript ausführen, das den Wert der Spalte c_defaults basierend auf dem Wert c_uid auswählt. Dies muss vom Datenbankbenutzer 'postgres' ausgeführt werden.

Auf der CLI kann ich Folgendes tun:

[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';

Wie erreiche ich dies jedoch durch ein Bash-Skript?

Das Ziel besteht darin, die Informationen aus dieser Spalte zu erhalten, sie zu bearbeiten und in diese Spalte zurückzuschreiben - alles über ein Bash-Skript.

29
rahuL

Probier diese:

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

Oder mit su:

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

Und auch Sudo:

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

Sie können eine Verbindung zu psql wie unten herstellen und Ihre SQL-Abfragen wie in eine normale Postgres-Funktion innerhalb des Blocks schreiben. Dort können bash-Variablen verwendet werden. Das Skript sollte jedoch ausschließlich SQL verwenden, auch für Kommentare, die Sie verwenden müssen - anstelle von #:

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

wenn Sie planen, es aus einer separaten SQL-Datei auszuführen. Hier ist ein gutes Beispiel (auf einer großartigen Seite, um zu lernen, wie man mit postgresql 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
11
shacharsol

Sobald Sie als postgres angemeldet sind, sollten Sie schreiben können:

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

um nur den Wert dieses Feldes auszudrucken, können Sie ihn beispielsweise in einer Bash-Variablen speichern:

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

Um die Anmeldung als postgres zu behandeln, empfehle ich die Verwendung von Sudo. Sie können einem bestimmten Benutzer die Berechtigung zum Ausführen erteilen

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

damit sie nur das eine Skript als postgres ausführen können.

7
ruakh

Die sicherste Methode, um Befehle an psql in einem Skript zu übergeben, besteht darin, einen String zu übergeben oder ein here-doc zu übergeben.

Die man docs für die -c/--command-Option gehen detaillierter vor, wenn dies vermieden werden sollte.

   -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

Um zu @Jasons Frage zu antworten, habe ich in meinem Bash-Skript so etwas (zu meinem Zweck) in der Kuppel: 

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

Der andere Weg ist es:

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

sie müssen jedoch mit dem Passwort sehr vorsichtig sein: Ich könnte kein Passwort mit einem ' und/oder einem : eingeben, um auf diese Weise zu arbeiten. Also am Ende aufgegeben.

-S 

0
MacUsers