Postgresql: Eksekusi skrip psql dengan kata sandi

274

Bagaimana saya bisa memanggil psql sehingga tidak meminta kata sandi ?

Inilah yang saya miliki:

psql -Umyuser < myscript.sql

Namun, saya tidak dapat menemukan argumen yang melewati kata sandi, dan karenanya psql selalu memintanya.

Axel Fontaine
sumber
4
Saya akhirnya pergi untuk variabel lingkungan PGPASSWORD. Ini cocok untuk penggunaan saya dengan sempurna. Sederhana dan mandiri dalam skrip.
Axel Fontaine
Baru saja menemukan postgresguide.com/utilities/psql.html
D_C

Jawaban:

315

Ada beberapa cara untuk mengautentikasi ke PostgreSQL. Anda mungkin ingin menyelidiki alternatif untuk otentikasi kata sandi di https://www.postgresql.org/docs/current/static/client-authentication.html .

Untuk menjawab pertanyaan Anda, ada beberapa cara memberikan kata sandi untuk otentikasi berbasis kata sandi. Cara yang jelas adalah melalui prompt kata sandi. Alih-alih itu, Anda dapat memberikan kata sandi dalam file pgpass atau melalui PGPASSWORDvariabel lingkungan. Lihat ini:

Tidak ada opsi untuk memberikan kata sandi sebagai argumen baris perintah karena informasi itu sering tersedia untuk semua pengguna, dan karenanya tidak aman. Namun, di lingkungan Linux / Unix Anda dapat memberikan variabel lingkungan untuk satu perintah seperti ini:

PGPASSWORD=yourpass psql ...
Reece
sumber
11
Saya pikir PGPASSWORD sudah usang tetapi masih berfungsi, btw. Just FYI
Scott Marlowe
35
Yap, sudah usang (dan dicatat di salah satu tautan). Karena sudah muncul, mungkin juga perlu dicatat bahwa penghinaan itu diperdebatkan dengan panas karena sangat berguna bagi banyak orang namun dapat digunakan dalam beberapa keadaan tanpa masalah keamanan yang serius. Sepertinya saya tidak lebih buruk daripada menyimpan .pgpass pada sistem file NFS, misalnya. Saya menggunakan PGPASSWORD secara rutin.
Reece
1
gagasan bahwa informasi baris perintah "tersedia untuk semua pengguna" didasarkan pada asumsi kuno tentang sistem multi-pengguna dan tidak berlaku di sebagian besar lingkungan modern di mana sistem hanya menjalankan satu aplikasi dan semuanya otomatis
Alex R
159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql
Greg
sumber
1
ini berfungsi dalam terraform juga. Anda, teman saya, adalah penyelamat
wildthing81
67

Anda dapat menambahkan baris perintah ini di awal skrip Anda:

set PGPASSWORD=[your password]
jbaylina
sumber
24
dalam kasus saya set perintah tidak berfungsi tetapi export PGPASSWORD=[password]berhasil
Can Kavaklıoğlu
itu tidak bekerja di skrip shell. Saya menggunakannya #!/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
Cobalah untuk tidak menggunakan spasi, mis. PGPASSWORD=password.
Ariejan
48

Jika Anda berniat memiliki banyak koneksi host / basis data, file ~ / .pgpass adalah cara yang harus dilakukan.

Langkah:

  1. Buat file menggunakan vim ~/.pgpassatau serupa. Masukkan informasi Anda dalam format berikut: hostname:port:database:username:passwordJangan tambahkan kutipan string di sekitar nilai bidang Anda. Anda juga dapat menggunakan * sebagai wildcard untuk bidang port / database Anda.
  2. Anda harus chmod 0600 ~/.pgpassagar itu tidak diabaikan secara diam-diam oleh psql.
  3. Buat alias di profil bash Anda yang menjalankan perintah psql untuk Anda. Sebagai contoh: alias postygresy='psql --host hostname database_name -U username'Nilai harus sesuai dengan yang Anda masukkan ke file ~ / .pgpass.
  4. Sumber profil bash Anda dengan . ~/.bashrcatau serupa.
  5. Ketikkan alias Anda dari baris perintah.

Perhatikan bahwa jika Anda memiliki set variabel PGPASSWORD = '' ekspor, itu akan diutamakan di atas file.

tandy
sumber
1
Anda harus melakukan chmod 600pada file, jika tidak psqldiam-diam akan mengabaikannya (menurut dokumen).
RichVel
33

Ini mungkin pertanyaan lama, tetapi ada metode alternatif yang dapat Anda gunakan yang belum disebutkan oleh siapa pun. Dimungkinkan untuk menentukan kata sandi secara langsung dalam koneksi URI. Dokumentasi dapat ditemukan di sini , atau di sini .

Anda dapat memberikan nama pengguna dan kata sandi Anda secara langsung dalam koneksi yang disediakan URI untuk psql:

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

Jika Anda mengalami masalah di windows seperti saya (saya menggunakan Windows 7 64-bit) dan set PGPASSWORD=[Password]tidak berfungsi.

Kemudian, seperti yang dikatakan Kavaklioglu di salah satu komentar,

export PGPASSWORD=[password]

Anda harus menyimpan ini di bagian atas file, atau sebelum penggunaan apa pun yang ditetapkan sebelum dipanggil.

Pasti bekerja di windows :)

Jamie Hutber
sumber
1
export PGPASSWORD=[password]tidak berfungsi untuk saya menggunakan baris perintah (cmd.exe) sama sekali. Apakah Anda yakin tidak menggunakan cygwin atau yang serupa?
Devin Snyder
Hanya berfungsi dengan cl, Anda menambahkannya ke file bukan? Sekarang ketikkan saja ke perintah?
Jamie Hutber
tidak apa-apa untuk menggunakannya di lingkungan linux / mac, untuk windows, saya pikir Anda harus menemukan cara untuk mengekspor variabel lingkungan ini.
Pengfei.X
Jadi tambahkan kata sandi global ... Itu ide yang menarik juga
Jamie Hutber
7

Mengingat masalah keamanan tentang penggunaan variabel lingkungan PGPASSWORD, saya pikir solusi keseluruhan terbaik adalah sebagai berikut:

  1. Tulis file pgpass sementara Anda sendiri dengan kata sandi yang ingin Anda gunakan.
  2. Gunakan variabel lingkungan PGPASSFILE untuk memberi tahu psql untuk menggunakan file itu.
  3. Hapus file pgpass sementara

Ada beberapa poin yang perlu diperhatikan di sini. Langkah 1 ada untuk menghindari mucking dengan file ~ / .pgpass pengguna yang mungkin ada. Anda juga harus memastikan bahwa file tersebut memiliki izin 0600 atau kurang.

Beberapa orang menyarankan memanfaatkan bash untuk pintas ini sebagai berikut:

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

Ini menggunakan sintaks <() untuk menghindari keharusan menulis data ke file yang sebenarnya. Tapi itu tidak berhasil karena psql memeriksa file apa yang sedang digunakan dan akan menimbulkan kesalahan seperti ini:

WARNING: password file "/dev/fd/63" is not a plain file
perkasa
sumber
Contoh kerja dari pendekatan ini muncul di stackoverflow.com/a/40614592/3696363 - jawaban lain untuk pertanyaan ini.
Eliyahu Skoczylas
Meskipun pengguna ini tidak benar-benar meminta hal yang sama yang saya cari, saya akan mengatakan bahwa pendekatannya tidak cocok. Saat menggunakan sintaks PGPASSFILE = <(apa pun), Anda dapat melakukan hal-hal seperti mendekripsi file dan hanya membuatnya ada di deskriptor file yang dibuat. Dengan menulis file temp, Anda tidak secara mendasar memecahkan masalah memiliki file pada disk dengan kredensial. Tidak menyenangkan berurusan dengan aturan industri yang sewenang-wenang seperti itu, tetapi itu adalah hal yang banyak orang tangani.
Desidero
7

Ini bisa dilakukan hanya dengan menggunakan PGPASSWORD. Saya menggunakan psql 9.5.10. Dalam kasus Anda solusinya adalah

PGPASSWORD=password psql -U myuser < myscript.sql

pyAddict
sumber
5

Membangun jawaban mightybyte bagi mereka yang tidak nyaman dengan skrip * nix shell, berikut ini skrip yang berfungsi:

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

Tanda dolar ganda ( $$) /tmp/pgpasswd$$pada baris 2 menambahkan nomor ID proses ke nama file, sehingga skrip ini dapat dijalankan lebih dari sekali, bahkan secara bersamaan, tanpa efek samping.

Perhatikan penggunaan chmodperintah pada baris 4 - seperti halnya kesalahan " bukan file biasa " yang mungkin dijelaskan, ada juga kesalahan " izin " jika ini tidak dilakukan.

Pada baris 7, Anda tidak perlu menggunakan server -hmyserver , -pmyport , atau -Ujdoe jika Anda menggunakan default ( localhost : 5432 ) dan hanya memiliki satu pengguna basis data. Untuk banyak pengguna, (tetapi koneksi default) ubah baris itu menjadi

psql mydb jdoe

Jangan lupa untuk membuat script executable dengan

chmod +x runpsql( atau apa pun yang Anda sebut file skrip )

MEMPERBARUI:

Saya mengambil saran RichVel dan membuat file tidak dapat dibaca sebelum memasukkan kata sandi ke dalamnya. Itu menutup sedikit lubang keamanan. Terima kasih!

Eliyahu Skoczylas
sumber
4
Anda dapat menggunakan mktempuntuk membuat file sementara alih-alih membuat skema penamaan Anda sendiri. Itu menciptakan file temp baru (bernama sesuatu seperti /tmp/tmp.ITXUNYgiNhdi Linux dan /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4di MacOS X) dan mencetak namanya ke stdout.
Ivan Kolmychek
1
Masalah keamanan Sebaiknya lakukan chmod 600setelah membuat file, tetapi sebelum menulis kata sandi. Seperti yang ditulis, skrip berbahaya di server dapat terus mencoba membaca file format ini, dan kadang-kadang berhasil mendapatkan kata sandi. Juga, jika skrip ini terganggu karena beberapa alasan, file tersebut akan dibiarkan di disk - menulis trappenangan shell akan membahas ini. Mengingat tidak mudah untuk membuat skrip yang aman seperti ini, saya sarankan untuk menggunakannya export PGPASSWORD.
RichVel
Terima kasih, @RichVel untuk menunjukkan lubang keamanan kecil itu. Sentuh membuat dan menjadikan file pribadi sebelum memasukkan kata sandi di dalamnya merupakan peningkatan yang pasti. Solusi semacam ini diperlukan karena PGPASSWORDtelah usang dalam 9.3.
Eliyahu Skoczylas
Beberapa dokumen mengatakan itu sudah usang tetapi seperti yang disebutkan dalam komentar di T&J ini , penghentian itu diperdebatkan dan masih berfungsi sampai Postgres 10.6
RichVel
5

Alternatif untuk menggunakan PGPASSWORDvariabel lingkungan adalah menggunakan conninfostring sesuai dengan dokumentasi

Cara alternatif untuk menentukan parameter koneksi adalah dalam string conninfo atau URI, yang digunakan sebagai ganti nama database. Mekanisme ini memberi Anda kendali yang sangat luas atas koneksi.

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

postgres=>
ubi
sumber
-1

Saya menemukan, psql menampilkan prompt kata sandi bahkan ketika Anda mendefinisikan variabel PGPASSWORD, tetapi Anda dapat menentukan opsi -w untuk psql untuk menghilangkan prompt kata sandi.

Mark Lokshin
sumber
-6

Gunakan -w pada perintah: psql -h localhost -p 5432 -U pengguna -w

vjOnstack
sumber