web-dev-qa-db-fra.com

PostgreSQL - requête du script bash en tant qu'utilisateur de base de données 'postgres'

J'ai une table dans ma base de données PostgreSQL qui a 3 colonnes - c_uid, c_defaults et c_settings. c_uid stocke simplement le nom d'un utilisateur et c_defaults est un long morceau de texte qui contient beaucoup de données avec cet utilisateur.

Je dois exécuter une instruction à partir d'un script bash qui sélectionne la valeur de la colonne c_defaults en fonction de la valeur c_uid et doit être effectuée par l'utilisateur de la base de données 'postgres'.

Sur la CLI, je peux effectuer les tâches suivantes:

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

Cependant, comment y parvenir à travers un script bash?

Le but est d’obtenir les informations de cette colonne, de les éditer et de les écrire dans cette colonne - tout au long d’un script bash.

29
rahuL

Essaye celui-là:

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

Ou en utilisant su:

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

Et aussi Sudo:

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

Vous pouvez vous connecter à psql comme ci-dessous et écrire vos requêtes SQL comme vous le faites dans une fonction postgres normale dans le bloc. Là, les variables bash peuvent être utilisées. Cependant, le script doit être strictement SQL, même pour les commentaires que vous devez utiliser - au lieu de #:

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

si vous prévoyez de l'exécuter à partir d'un fichier SQL séparé. voici un bon exemple (tiré d'une page formidable pour apprendre à utiliser basg avec 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

Une fois connecté en tant que postgres, vous devriez pouvoir écrire:

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

pour n'imprimer que la valeur de ce champ, ce qui signifie que vous pouvez le capturer (par exemple) dans une variable Bash

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

Pour gérer la connexion en tant que postgres, je vous recommande d’utiliser Sudo. Vous pouvez donner à un utilisateur spécifique l'autorisation d'exécuter

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

afin qu’ils ne puissent exécuter que le seul script en tant que postgres.

7
ruakh

Le moyen le plus sûr de passer des commandes à psql dans un script consiste à rediriger une chaîne ou à transmettre un here-doc.

La documentation relative à l'option -c/--command entre dans les détails lorsqu'elle doit être évitée.

   -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

Pour répondre à la question de @Jason, dans mon script bash, j'ai écrit quelque chose comme ça (pour mon propos): 

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

Une autre façon de le faire est:

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

mais vous devez faire très attention au mot de passe: je ne pouvais pas créer un mot de passe avec un ' et/ou un : pour travailler de cette façon Alors abandonné à la fin.

-S 

0
MacUsers