Postgresql: Skript-Ausführung von psql mit Passwort

274

Wie kann ich psql aufrufen , damit kein Passwort abgefragt wird ?

Das habe ich:

psql -Umyuser < myscript.sql

Ich konnte jedoch das Argument nicht finden, das das Kennwort übergibt, und daher fordert psql immer dazu auf.

Axel Fontaine
quelle
4
Am Ende habe ich mich für die Umgebungsvariable PGPASSWORD entschieden. Dies passte perfekt zu meinem Anwendungsfall. Einfach und in sich geschlossen im Skript.
Axel Fontaine
Habe
D_C
Mögliches Duplikat von Wie gebe ich ein Passwort für psql nicht interaktiv an?
Helder Pereira

Antworten:

315

Es gibt verschiedene Möglichkeiten, sich bei PostgreSQL zu authentifizieren. Möglicherweise möchten Sie unter https://www.postgresql.org/docs/current/static/client-authentication.html nach Alternativen zur Kennwortauthentifizierung suchen .

Um Ihre Frage zu beantworten, gibt es verschiedene Möglichkeiten, ein Kennwort für die kennwortbasierte Authentifizierung bereitzustellen. Der naheliegende Weg ist über die Passwortabfrage. Stattdessen können Sie das Kennwort in einer pgpass-Datei oder über die PGPASSWORDUmgebungsvariable angeben . Siehe diese:

Es gibt keine Option, das Kennwort als Befehlszeilenargument anzugeben, da diese Informationen häufig allen Benutzern zur Verfügung stehen und daher unsicher sind. In Linux / Unix-Umgebungen können Sie jedoch eine Umgebungsvariable für einen einzelnen Befehl wie den folgenden bereitstellen:

PGPASSWORD=yourpass psql ...
Reece
quelle
11
Ich denke, PGPASSWORD ist veraltet, funktioniert aber übrigens immer noch. Nur zu Ihrer Information
Scott Marlowe
35
Ja, es ist veraltet (und so in einem der Links vermerkt). Da es aufgetaucht ist, ist es wahrscheinlich auch erwähnenswert, dass die Abwertung heiß umkämpft ist, da sie für viele Menschen äußerst nützlich ist und unter bestimmten Umständen ohne ernsthafte Sicherheitsbedenken verwendet werden kann. Es scheint mir nicht schlimmer zu sein, als beispielsweise .pgpass in einem NFS-Dateisystem zu speichern. Ich benutze PGPASSWORD routinemäßig.
Reece
1
Die Idee, dass Befehlszeileninformationen "allen Benutzern zur Verfügung stehen", basiert auf veralteten Annahmen über Mehrbenutzersysteme und gilt nicht in den meisten modernen Umgebungen, in denen Systeme nur eine einzige Anwendung ausführen und alles automatisiert ist
Alex R
159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql
Greg
quelle
1
Dies funktioniert auch in Terraform. Sie, mein Freund, sind ein Lebensretter
wildthing81
67

Sie können diese Befehlszeile zu Beginn Ihres Skripts hinzufügen:

set PGPASSWORD=[your password]
jbaylina
quelle
24
In meinem Fall hat der Befehl set nicht funktioniert, export PGPASSWORD=[password]aber funktioniert
Can Kavaklıoğlu
Es funktioniert nicht in Shell-Skript. Ich benutze es #!/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
Versuchen Sie, keine Leerzeichen zu verwenden, z. PGPASSWORD=password.
Ariejan
48

Wenn Sie mehrere Hosts / Datenbankverbindungen haben möchten, ist die Datei ~ / .pgpass der richtige Weg.

Schritte:

  1. Erstellen Sie die Datei mit vim ~/.pgpassoder ähnlich. Geben Sie Ihre Informationen im folgenden Format ein: hostname:port:database:username:passwordFügen Sie keine Zeichenfolgen um Ihre Feldwerte ein. Sie können * auch als Platzhalter für Ihre Port- / Datenbankfelder verwenden.
  2. Sie müssen chmod 0600 ~/.pgpass, damit es von psql nicht stillschweigend ignoriert wird.
  3. Erstellen Sie einen Alias ​​in Ihrem Bash-Profil, der Ihren psql-Befehl für Sie ausführt. Beispiel: alias postygresy='psql --host hostname database_name -U username'Die Werte sollten mit denen übereinstimmen, die Sie in die Datei ~ / .pgpass eingegeben haben.
  4. Geben Sie Ihr Bash-Profil mit . ~/.bashrcoder ähnlich ein.
  5. Geben Sie Ihren Alias ​​über die Befehlszeile ein.

Beachten Sie, dass eine Exportvariable PGPASSWORD = '' Vorrang vor der Datei hat.

Tandy
quelle
1
Sie müssen eine chmod 600Datei bearbeiten, andernfalls psqlwird sie stillschweigend ignoriert (gemäß den Dokumenten).
RichVel
33

Dies mag eine alte Frage sein, aber es gibt eine alternative Methode, die Sie verwenden können und die niemand erwähnt hat. Es ist möglich, das Passwort direkt in der Verbindungs-URI anzugeben. Die Dokumentation finden Sie hier , alternativ hier .

Sie können Ihren Benutzernamen und Ihr Passwort direkt in der Verbindungs-URI angeben, die für Folgendes bereitgestellt wird psql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb
ajxs
quelle
2
Postrgres 9.3 ignoriert UmgebungsvariablePGPASSWORD
david.perez
14

Wenn Sie Probleme unter Windows wie mir haben (ich verwende Windows 7 64-Bit) und set PGPASSWORD=[Password]nicht funktioniert haben.

Dann, wie Kavaklioglu in einem der Kommentare sagte,

export PGPASSWORD=[password]

Sie müssen dies oben in der Datei oder vor jeder Verwendung speichern, damit es vor dem Aufruf festgelegt wird.

Funktioniert sicherlich unter Windows :)

Jamie Hutber
quelle
1
export PGPASSWORD=[password]funktioniert bei mir überhaupt nicht über die Kommandozeile (cmd.exe). Bist du sicher, dass du kein Cygwin oder ähnliches benutzt hast?
Devin Snyder
Funktioniert nur mit cl, du hast es der Datei hinzugefügt, oder? Jetzt nur noch in Befehl eingegeben?
Jamie Hutber
Es ist in Ordnung, es in einer Linux / Mac-Umgebung zu verwenden. Für Windows sollten Sie einen Weg finden, diese Umgebungsvariable zu exportieren.
Pengfei.X
Fügen Sie
7

Angesichts der Sicherheitsbedenken hinsichtlich der Verwendung der Umgebungsvariablen PGPASSWORD denke ich, dass die beste Gesamtlösung folgende ist:

  1. Schreiben Sie Ihre eigene temporäre pgpass-Datei mit dem Passwort, das Sie verwenden möchten.
  2. Verwenden Sie die Umgebungsvariable PGPASSFILE, um psql anzuweisen, diese Datei zu verwenden.
  3. Entfernen Sie die temporäre pgpass-Datei

Hier gibt es einige wichtige Punkte. Schritt 1 ist da, um zu vermeiden, dass die ~ / .pgpass-Datei des Benutzers, die möglicherweise vorhanden ist, durcheinander gebracht wird. Sie müssen auch sicherstellen, dass die Datei die Berechtigungen 0600 oder weniger hat.

Einige haben vorgeschlagen, Bash zu nutzen, um dies wie folgt zu verknüpfen:

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

Hierbei wird die Syntax <() verwendet, um zu vermeiden, dass die Daten in eine tatsächliche Datei geschrieben werden müssen. Dies funktioniert jedoch nicht, da psql überprüft, welche Datei verwendet wird, und einen Fehler wie den folgenden auslöst:

WARNING: password file "/dev/fd/63" is not a plain file
mächtiges Byte
quelle
Ein funktionierendes Beispiel für diesen Ansatz finden Sie unter stackoverflow.com/a/40614592/3696363 - eine weitere Antwort auf diese Frage.
Eliyahu Skoczylas
Obwohl dieser Benutzer nicht wirklich nach dem gefragt hat, wonach ich suche, würde ich sagen, dass der Ansatz nicht übereinstimmt. Wenn Sie die Syntax PGPASSFILE = <(was auch immer) verwenden, können Sie beispielsweise eine Datei entschlüsseln und sie nur im erstellten Dateideskriptor enthalten. Durch das Schreiben einer temporären Datei lösen Sie das Problem einer Datei auf der Festplatte mit Anmeldeinformationen nicht grundlegend. Es macht keinen Spaß, mit solchen willkürlichen Branchenregeln umzugehen, aber es ist eine Sache, mit der sich viele Menschen befassen.
Desidero
7

Dies kann einfach mit PGPASSWORD erfolgen. Ich benutze psql 9.5.10. In Ihrem Fall wäre die Lösung

PGPASSWORD=password psql -U myuser < myscript.sql

pyAddict
quelle
5

Aufbauend auf der Antwort von mächtigen Byte für diejenigen, die mit * nix Shell- Skripten nicht vertraut sind , ist hier ein funktionierendes Skript:

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

Das doppelte Dollarzeichen ( $$) in /tmp/pgpasswd$$Zeile 2 hängt die Prozess-ID-Nummer an den Dateinamen an, sodass dieses Skript mehr als einmal und sogar gleichzeitig ohne Nebenwirkungen ausgeführt werden kann.

Beachten Sie die Verwendung des chmodBefehls in Zeile 4 - genau wie der Fehler " Keine einfache Datei ", der möglicherweise beschrieben wird, gibt es auch einen Fehler " Berechtigungen ", wenn dies nicht erfolgt.

In Zeile 7 müssen Sie nicht das -hFlag myserver , -pmyport oder -Ujdoe verwenden, wenn Sie die Standardeinstellungen ( localhost : 5432 ) verwenden und nur einen Datenbankbenutzer haben. Ändern Sie für mehrere Benutzer (aber die Standardverbindung) diese Zeile in

psql mydb jdoe

Vergessen Sie nicht, das Skript mit ausführbar zu machen

chmod +x runpsql( oder wie auch immer Sie die Skriptdatei genannt haben )

AKTUALISIEREN:

Ich habe den Rat von RichVel befolgt und die Datei unlesbar gemacht, bevor ich das Passwort eingegeben habe. Das schließt eine kleine Sicherheitslücke. Vielen Dank!

Eliyahu Skoczylas
quelle
4
Sie können mktempeine temporäre Datei erstellen, anstatt ein eigenes Namensschema zu erstellen. Es erstellt eine neue temporäre Datei (etwa /tmp/tmp.ITXUNYgiNhunter Linux und /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4MacOS X) und druckt ihren Namen in stdout.
Ivan Kolmychek
1
Sicherheitsproblem Es ist am besten, dies chmod 600nach dem Erstellen der Datei zu tun , aber bevor Sie das Kennwort darauf schreiben. Wie geschrieben, könnte ein bösartiges Skript auf dem Server ständig versuchen, Dateien dieses Formats zu lesen, und manchmal gelang es ihm, das Kennwort zu erhalten. Wenn dieses Skript aus irgendeinem Grund unterbrochen wird, bleibt die Datei auf der Festplatte - das Schreiben eines Shell- trapHandlers würde dies beheben. Da es nicht trivial ist, ein sicheres Skript wie dieses zu schreiben, empfehle ich stattdessen die Verwendung export PGPASSWORD.
RichVel
Vielen Dank, @RichVel, dass Sie auf diese kleine Sicherheitslücke hingewiesen haben. Berühren Sie das Erstellen und Privatisieren der Datei, bevor Sie das Kennwort eingeben. Dies ist eine deutliche Verbesserung. Diese Art von Lösung wird benötigt, da PGPASSWORDsie in 9.3 veraltet ist.
Eliyahu Skoczylas
Einige der Dokumente sagen, dass es veraltet ist, aber wie in einem Kommentar in dieser
Frage und Antwort erwähnt
5

Eine Alternative zur Verwendung von PGPASSWORDUmgebungsvariablen ist die Verwendung einer conninfoZeichenfolge gemäß der Dokumentation

Eine alternative Möglichkeit, Verbindungsparameter anzugeben, besteht in einer Conninfo-Zeichenfolge oder einem URI, der anstelle eines Datenbanknamens verwendet wird. Dieser Mechanismus gibt Ihnen eine sehr breite Kontrolle über die Verbindung.

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

postgres=>
ubi
quelle
-1

Ich finde, dass psql Passwort-Eingabeaufforderung anzeigen, selbst wenn Sie die Variable PGPASSWORD definieren, aber Sie können die Option -w angeben, damit psql die Passwort-Eingabeaufforderung weglässt.

Mark Lokshin
quelle
-6

Verwenden Sie -w im Befehl: psql -h localhost -p 5432 -U Benutzer -w

vjOnstack
quelle