I am trying to automate database creation process with a shell script and one thing I've hit a road block with passing a password to psql. Here is a bit of code from the shell script:
psql -U $DB_USER -h localhost -c"$DB_RECREATE_SQL"
How do I pass a password to psql
in a non-interactive way?
Set the PGPASSWORD environment variable inside the script before calling psql
PGPASSWORD=pass1234 psql -U MyUsername myDatabaseName
For reference, see http://www.postgresql.org/docs/current/static/libpq-envars.html
Edit
Since Postgres 9.2 there is also the option to specify a connection string or URI that can contain the username and password. Syntax is:
$ psql postgresql://[user[:password]@][host][:port][,...][/dbname][?param1=value1&...]
Using that is a security risk because the password is visible in plain text when looking at the command line of a running process e.g. using ps
(Linux), ProcessExplorer (Windows) or similar tools, by other users.
See also this question on Database Administrators
From the official documentation:
It is also convenient to have a ~/.pgpass file to avoid regularly having to type in passwords. See Section 30.13 for more information.
...
This file should contain lines of the following format:
hostname:port:database:username:password
The password field from the first line that matches the current connection parameters will be used.
chmod go-rwx .pgpass
in one line: export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command' with command a sql command such as "select * from schema.table"
or more readable: export PGPASSWORD='password' psql -h 'server name' -U 'user name' -d 'base name' \ -c 'command' (eg. "select * from schema.table")
PGPASSWORD='password' psql ....
which also has the benefit of the variable not being accessible after the command is done.
export PGPASSWORD=YourNewPassword
worked for me over other variations.
export PGPASSWORD
sounds like a really bad idea
PGPASSWORD
.
I tend to prefer passing a URL to psql:
psql "postgresql://$DB_USER:$DB_PWD@$DB_SERVER/$DB_NAME"
This gives me the freedom to name my environment variables as I wish and avoids creating unnecessary files.
This requires libpq
. The documentation can be found here.
On Windows:
Assign value to PGPASSWORD: C:\>set PGPASSWORD=pass Run command: C:\>psql -d database -U user
Ready
Or in one line,
set PGPASSWORD=pass&& psql -d database -U user
Note the lack of space before the && !
-w
also.
PGPASSWORD=xxxx psql -U username -d database -w -c "select * from foo;"
works.
$env:PGPASSWORD=pass; psql -d database -U user
This can be done by creating a .pgpass
file in the home directory of the (Linux) User. .pgpass
file format:
<databaseip>:<port>:<databasename>:<dbusername>:<password>
You can also use wild card *
in place of details.
Say I wanted to run tmp.sql
without prompting for a password.
With the following code you can in *.sh file
echo "192.168.1.1:*:*:postgres:postgrespwd" > $HOME/.pgpass
echo "` chmod 0600 $HOME/.pgpass `"
echo " ` psql -h 192.168.1.1 -p 5432 -U postgres postgres -f tmp.sql `
An alternative to using the PGPASSWORD
environment variable is to use the conninfo
string according to the documentation:
An alternative way to specify connection parameters is in a conninfo string or a URI, which is used instead of a database name. This mechanism give you very wide control over the connection.
$ psql "host=<server> port=5432 dbname=<db> user=<user> password=<password>"
postgres=>
ps a
command by any (non-root) user
If its not too late to add most of the options in one answer:
There are a couple of options:
set it in the pgpass file. link
set an environment variable and get it from there: export PGPASSWORD='password' and then run your psql to login or even run the command from there: psql -h clustername -U username -d testdb On windows you will have to use "set" : set PGPASSWORD=pass and then login to the psql bash. Pass it via URL & env variable: psql "postgresql://$USER_NAME:$PASSWORD@$HOST_NAME/$DB_NAME"
Added content of pg_env.sh to my .bashrc:
cat /opt/PostgreSQL/10/pg_env.sh
#!/bin/sh
# The script sets environment variables helpful for PostgreSQL
export PATH=/opt/PostgreSQL/10/bin:$PATH
export PGDATA=/opt/PostgreSQL/10/data
export PGDATABASE=postgres
export PGUSER=postgres
export PGPORT=5433
export PGLOCALEDIR=/opt/PostgreSQL/10/share/locale
export MANPATH=$MANPATH:/opt/PostgreSQL/10/share/man
with addition of (as per user4653174 suggestion)
export PGPASSWORD='password'
Just to add more clarity.
You can assign the password to the PGPASSWORD
variable.
So instead of the below which will require you to type the password:
psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --password --dbname=postgres
We will replace the --password
flag with PGPASSWORD=QghyumjB3ZtCQkdf
. So it will be:
PGPASSWORD=QghyumjB3ZtCQkdf psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --dbname=postgres
This way you will not be required to type the password.
Success story sharing
space
in the command line before the first character and the command won't be stored in bash history. Works for ubuntu/bash.docker run -e PGPASSWORD="$(pbpaste)" --rm postgres psql -h www.example.com dbname username -c 'SELECT * FROM table;'
ps -ef
), and 2) will add it to your shell's history file (e.g..bash_history
). My recommendation is to store the password in a safe file (e.g. use OS-level permissions to restrict access) and thenPGPASSWORD=$(cat /<path>/to/secret.txt) ...
.