Postgresql: exécution de script psql avec mot de passe

274

Comment puis-je appeler psql pour qu'il ne demande pas de mot de passe ?

Voici ce que j'ai:

psql -Umyuser < myscript.sql

Cependant, je n'ai pas pu trouver l'argument qui transmet le mot de passe, et donc psql le demande toujours.

Axel Fontaine
la source
4
J'ai fini par aller pour la variable d'environnement PGPASSWORD. Cela correspondait parfaitement à mon cas d'utilisation. Simple et autonome dans le script.
Axel Fontaine
Je viens de trouver ce postgresguide.com/utilities/psql.html
D_C

Réponses:

315

Il existe plusieurs façons de s'authentifier auprès de PostgreSQL. Vous pouvez rechercher des alternatives à l'authentification par mot de passe sur https://www.postgresql.org/docs/current/static/client-authentication.html .

Pour répondre à votre question, il existe plusieurs façons de fournir un mot de passe pour l'authentification par mot de passe. La manière évidente est via l'invite de mot de passe. Au lieu de cela, vous pouvez fournir le mot de passe dans un fichier pgpass ou via la PGPASSWORDvariable d'environnement. Voir ces:

Il n'y a pas d'option pour fournir le mot de passe comme argument de ligne de commande car ces informations sont souvent disponibles pour tous les utilisateurs, et donc non sécurisées. Cependant, dans les environnements Linux / Unix, vous pouvez fournir une variable d'environnement pour une seule commande comme celle-ci:

PGPASSWORD=yourpass psql ...
Reece
la source
11
Je pense que PGPASSWORD est obsolète mais fonctionne toujours, btw. Juste pour info
Scott Marlowe
35
Oui, c'est obsolète (et ainsi noté dans l'un des liens). Depuis son apparition, il convient également de noter que la dépréciation est vivement contestée car elle est extrêmement utile pour de nombreuses personnes mais peut être utilisée dans certaines circonstances sans graves problèmes de sécurité. Il me semble que ce n'est pas pire que de stocker .pgpass sur un système de fichiers NFS, par exemple. J'utilise PGPASSWORD régulièrement.
Reece
1
l'idée que les informations de ligne de commande sont "disponibles pour tous les utilisateurs" est basée sur des hypothèses désuètes sur les systèmes multi-utilisateurs et ne s'applique pas dans la plupart des environnements modernes où les systèmes exécutent simplement une seule application et sont entièrement automatisés
Alex R
159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql
Greg
la source
1
cela fonctionne aussi en terraform. vous, mon ami, êtes une
bouée de
67

Vous pouvez ajouter cette ligne de commande au début de votre script:

set PGPASSWORD=[your password]
jbaylina
la source
24
dans mon cas, la commande set n'a pas fonctionné mais export PGPASSWORD=[password]a fonctionné
Can Kavaklıoğlu
cela ne fonctionne pas dans le script shell. Je l'utilise #!/bin/sh set PGPASSWORD = postgres psql -h 192.168.3.200 -U postgres incx_um << EOF DELETE FROM usrmgt.user_one_time_codes WHERE time < NOW() - INTERVAL '30 minute' EOF
Govind Gupta
2
Essayez de ne pas utiliser d'espaces, par exemple. PGPASSWORD=password.
Ariejan
48

Si vous avez l'intention d'avoir plusieurs hôtes / connexions à la base de données, le fichier ~ / .pgpass est la solution.

Pas:

  1. Créez le fichier à l'aide de vim ~/.pgpassou similaire. Saisissez vos informations dans le format suivant: hostname:port:database:username:passwordN'ajoutez pas de guillemets autour de vos valeurs de champ. Vous pouvez également utiliser * comme caractère générique pour vos champs de port / base de données.
  2. Vous devez chmod 0600 ~/.pgpasspour qu'il ne soit pas ignoré silencieusement par psql.
  3. Créez un alias dans votre profil bash qui exécute votre commande psql pour vous. Par exemple: alias postygresy='psql --host hostname database_name -U username'les valeurs doivent correspondre à celles que vous avez entrées dans le fichier ~ / .pgpass.
  4. Sourcez votre profil bash avec . ~/.bashrcou similaire.
  5. Tapez votre alias depuis la ligne de commande.

Notez que si vous avez un jeu de variables d'exportation PGPASSWORD = '', il aura priorité sur le fichier.

tandy
la source
1
Vous devez faire un chmod 600sur le fichier, sinon vous psqll'ignorerez silencieusement (selon les documents).
RichVel
33

C'est peut-être une vieille question, mais il existe une autre méthode que vous n'avez pas mentionnée. Il est possible de spécifier le mot de passe directement dans l'URI de connexion. La documentation peut être trouvée ici , ou ici .

Vous pouvez fournir votre nom d'utilisateur et votre mot de passe directement dans l'URI de connexion fourni à psql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb
ajxs
la source
2
Postrgres 9.3 ignore la variable d'environnementPGPASSWORD
david.perez
14

Si vous rencontrez des problèmes sur Windows comme moi (j'utilise Windows 7 64 bits) et que set PGPASSWORD=[Password]cela ne fonctionne pas.

Ensuite, comme l'a dit Kavaklioglu dans l'un des commentaires,

export PGPASSWORD=[password]

Vous devrez l'enregistrer en haut du fichier, ou avant toute utilisation, donc son ensemble avant d'être appelé.

Fonctionne certainement sur Windows :)

Jamie Hutber
la source
1
export PGPASSWORD=[password]ne fonctionne pas du tout en utilisant la ligne de commande (cmd.exe). Êtes-vous sûr de ne pas utiliser cygwin ou quelque chose de similaire?
Devin Snyder
Fonctionne uniquement avec cl, vous l'avez ajouté au fichier non? Maintenant, vous venez de le taper dans la commande?
Jamie Hutber
c'est ok de l'utiliser dans un environnement linux / mac, pour windows, je pense que vous devriez trouver un moyen d'exporter cette variable d'environnement.
Pengfei.X
Alors ajoutez un mot de passe global ... C'est aussi une idée intéressante
Jamie Hutber
7

Étant donné les problèmes de sécurité liés à l'utilisation de la variable d'environnement PGPASSWORD, je pense que la meilleure solution globale est la suivante:

  1. Écrivez votre propre fichier pgpass temporaire avec le mot de passe que vous souhaitez utiliser.
  2. Utilisez la variable d'environnement PGPASSFILE pour indiquer à psql d'utiliser ce fichier.
  3. Supprimez le fichier pgpass temporaire

Il y a quelques points à noter ici. L'étape 1 est là pour éviter le nettoyage avec le fichier ~ / .pgpass de l'utilisateur qui pourrait exister. Vous devez également vous assurer que le fichier dispose des autorisations 0600 ou moins.

Certains ont suggéré de tirer parti de bash pour raccourcir cela comme suit:

PGPASSFILE=<(echo myserver:5432:mydb:jdoe:password) psql -h myserver -U jdoe -p 5432 mydb

Cela utilise la syntaxe <() pour éviter d'avoir à écrire les données dans un fichier réel. Mais cela ne fonctionne pas car psql vérifie quel fichier est utilisé et générera une erreur comme celle-ci:

WARNING: password file "/dev/fd/63" is not a plain file
puissant
la source
Un exemple de travail de cette approche apparaît dans stackoverflow.com/a/40614592/3696363 - une autre réponse à cette question.
Eliyahu Skoczylas
Bien que cet utilisateur n'ait pas vraiment demandé la même chose que je recherche, je dirais que l'approche ne correspond pas. Lorsque vous utilisez la syntaxe PGPASSFILE = <(quelle que soit), vous pouvez effectuer des opérations telles que décrypter un fichier et le faire uniquement figurer dans le descripteur de fichier créé. En écrivant un fichier temporaire, vous ne résolvez pas fondamentalement le problème d'avoir un fichier sur le disque avec des informations d'identification. Ce n'est pas amusant de traiter des règles arbitraires de l'industrie comme ça, mais c'est une chose à laquelle beaucoup de gens doivent faire face.
Desidero
7

Cela peut être fait simplement en utilisant PGPASSWORD. J'utilise psql 9.5.10. Dans votre cas, la solution serait

PGPASSWORD=password psql -U myuser < myscript.sql

pyAddict
la source
5

S'appuyant sur la réponse de mightybyte pour ceux qui ne sont pas à l'aise avec les scripts shell * nix , voici un script de travail:

#!/bin/sh
PGPASSFILE=/tmp/pgpasswd$$
touch $PGPASSFILE
chmod 600 $PGPASSFILE
echo "myserver:5432:mydb:jdoe:password" > $PGPASSFILE
export PGPASSFILE
psql mydb
rm $PGPASSFILE

Le double signe dollar ( $$) /tmp/pgpasswd$$à la ligne 2 ajoute le numéro d'identification du processus au nom du fichier, afin que ce script puisse être exécuté plusieurs fois, même simultanément, sans effets secondaires.

Notez l'utilisation de la chmodcommande à la ligne 4 - tout comme l' erreur " pas un fichier ordinaire " qui pourrait être décrite, il y a aussi une erreur " autorisations " si cela n'est pas fait.

À la ligne 7, vous n'aurez pas à utiliser le drapeau -hmyserver , -pmyport ou -Ujdoe si vous utilisez les valeurs par défaut ( localhost : 5432 ) et que vous n'avez qu'un seul utilisateur de base de données. Pour plusieurs utilisateurs (mais la connexion par défaut), remplacez cette ligne par

psql mydb jdoe

N'oubliez pas de rendre le script exécutable avec

chmod +x runpsql( ou ce que vous avez appelé le fichier de script )

METTRE À JOUR:

J'ai suivi les conseils de RichVel et rendu le fichier illisible avant d'y mettre le mot de passe. Cela ferme un léger trou de sécurité. Merci!

Eliyahu Skoczylas
la source
4
Vous pouvez utiliser mktemppour créer un fichier temporaire au lieu de créer votre propre schéma de dénomination. Il crée un nouveau fichier temporaire (nommé quelque chose comme /tmp/tmp.ITXUNYgiNhsous Linux et /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4sur MacOS X) et imprime son nom sur stdout.
Ivan Kolmychek
1
Problème de sécurité Il est préférable de le faire chmod 600après avoir créé le fichier, mais avant d'y écrire le mot de passe. Tel qu'il est écrit, un script malveillant sur le serveur pourrait continuellement essayer de lire des fichiers de ce format et réussirait parfois à obtenir le mot de passe. De plus, si ce script est interrompu pour une raison quelconque, le fichier sera laissé sur le disque - l'écriture d'un trapgestionnaire de shell résoudrait ce problème. Étant donné qu'il n'est pas trivial d'écrire un script sécurisé comme celui-ci, je recommande d'utiliser à la export PGPASSWORDplace.
RichVel
Merci, @RichVel d'avoir signalé ce petit trou de sécurité. Touchez créer et rendre le fichier privé avant d'y mettre le mot de passe est une nette amélioration. Ce type de solution est nécessaire car il PGPASSWORDest obsolète en 9.3.
Eliyahu Skoczylas
Certains docs disent que c'est obsolète mais comme mentionné dans un commentaire dans ce Q&R , la dépréciation est contestée et cela fonctionne toujours à partir de Postgres 10.6
RichVel
5

Une alternative à l'utilisation de PGPASSWORDla variable d'environnement consiste à utiliser une conninfochaîne conformément à la documentation

Une autre façon de spécifier les paramètres de connexion est dans une chaîne conninfo ou un URI, qui est utilisé à la place d'un nom de base de données. Ce mécanisme vous donne un contrôle très large sur la connexion.

$ psql "host=<server> port=5432 dbname=<db> user=<user> password=<password>"

postgres=>
ubi
la source
-1

Je trouve, que psql affiche l'invite de mot de passe même si vous définissez la variable PGPASSWORD, mais vous pouvez spécifier l'option -w pour psql pour omettre l'invite de mot de passe.

Mark Lokshin
la source
-6

Utilisez -w dans la commande: psql -h localhost -p 5432 -U user -w

vjOnstack
la source