Como especificar uma senha para 'psql' não interativamente?

337

Eu estou tentando automatizar o processo de criação de banco de dados com um script de shell e uma coisa que eu encontrei em um obstáculo ao passar uma senha para o psql . Aqui está um pouco de código do script de shell:

psql -U $DB_USER -h localhost -c"$DB_RECREATE_SQL"

Como passar uma senha de psqlforma não interativa?

Alex N.
fonte
11
Você pode usar um URL de conexão. Verifique estas respostas em stackoverflow.com/questions/3582552/postgres-connection-url .
paulodiovani 19/09/17

Respostas:

141

A partir da documentação oficial :

Também é conveniente ter um arquivo ~ / .pgpass para evitar a digitação regular de senhas. Consulte a Seção 30.13 para obter mais informações.

...

Este arquivo deve conter linhas do seguinte formato:

hostname:port:database:username:password

O campo de senha da primeira linha que corresponde aos parâmetros de conexão atuais será usado.

Flimzy
fonte
29
Obrigado, eu estou ciente do pgpass, mas isso não resolve o problema - eu preciso de um script bash independente para operar sobre o banco de dados, daí a minha pergunta sobre a transmissão de informações ao psql via linha de comando.
Alex N.
6
Eu acho que sua única opção é configurar um arquivo .pgpass ao qual seu script bash tem acesso. Ou não use senhas - você pode configurar outra forma de autenticação, como ident, ou usar certificados SSL.
Flimzy
É isso que eu temia :) Obrigado pela informação!
Alex N.
Outra opção pode ser usar expect. Mas eu realmente odeio esperar :)
Flimzy
11
Não se esqueça de remover o grupo e outras permissões de usuário para ler, escrever, executar o arquivo .pgpass! Executechmod go-rwx .pgpass
Vladislavs Dovgalecs
610

Defina a variável de ambiente PGPASSWORD dentro do script antes de chamar o psql

PGPASSWORD=pass1234 psql -U MyUsername myDatabaseName

Para referência, consulte http://www.postgresql.org/docs/current/static/libpq-envars.html


Editar

Desde o Postgres 9.2, também existe a opção de especificar uma cadeia de conexão ou URI que possa conter o nome de usuário e a senha.

Usar isso é um risco à segurança, porque a senha é visível em texto sem formatação quando se olha para a linha de comando de um processo em execução, por exemplo, usando ps(Linux), ProcessExplorer (Windows) ou ferramentas similares, por outros usuários.

Consulte também esta pergunta em Administradores de banco de dados

um cavalo sem nome
fonte
32
Por exemplo, em uma linha que você pode fazer algo como: PGPASSWORD = pass1234 psql -u myusername myusername
andyortlieb
3
Eu acho que essa é a maneira mais conveniente para simplesmente executar um script SQL.
Zr870
2
Só posso adicionar - adicione um spacena linha de comando antes do primeiro caractere e o comando não será armazenado no histórico do bash. Funciona para ubuntu / bash.
Balder
5
BÔNUS: Trabalhos para o Docker:docker run -e PGPASSWORD="$(pbpaste)" --rm postgres psql -h www.example.com dbname username -c 'SELECT * FROM table;'
Bilal Akil
3
Tenha cuidado e certifique-se sempre adicionar um espaço anterior caso contrário ele vai aparecer em seu histórico do bash arquivo ~ / .bash_history ...
rogerdpack
102
  • em uma linha:

    export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command'

    com comando um comando sql como"select * from schema.table"

  • ou mais legível:

    export PGPASSWORD='password'
    psql -h 'server name' -U 'user name' -d 'base name' \
         -c 'command' (eg. "select * from schema.table")
user4653174
fonte
18
A única linha pode ser um pouco simplificada para: PGPASSWORD='password' psql .... que também tem o benefício de a variável não estar acessível após a conclusão do comando.
21416 Garrett
3
export PGPASSWORD=YourNewPasswordtrabalhou para mim sobre outras variações.
Mikeumus #
7
export PGPASSWORDSoa como uma péssima idéia
Hasen
11
Isso salvará a senha no arquivo bash history ~ / .bash_history (a menos que você sempre adicione sempre um espaço anterior) e também exporta a senha para o seu ambiente atual FWIW: |
Rogerdpack
67

Costumo preferir passar um URL para o psql :

psql "postgresql://$DB_USER:$DB_PWD@$DB_SERVER/$DB_NAME"

Isso me dá a liberdade de nomear minhas variáveis ​​de ambiente conforme desejo e evita a criação de arquivos desnecessários.

Isso requer libpq. A documentação pode ser encontrada aqui .

Jacques Gaudin
fonte
você pode usar algo assim com pg_restore? Obrigado!
the_ccalderon
11
@ ccalderon911217 Aparentemente você pode: stackoverflow.com/a/28359470/1388292
Jacques Gaudin
@JacquesGaudin sim me testou! Obrigado!
the_ccalderon
26

No Windows:

  1. Atribua valor a PGPASSWORD: C:\>set PGPASSWORD=pass

  2. Comando de execução: C:\>psql -d database -U user

pronto

Ou em uma linha,

set PGPASSWORD=pass&& psql -d database -U user

Observe a falta de espaço antes do &&!

JAGJ jdfoxito
fonte
11
Eu tentei isso e não funcionou. Ainda está sendo solicitada uma senha.
Antipattern
11
@antipattern Você também deve passar a opção -w.
mljrg 27/07/2018
11
PGPASSWORD=xxxx psql -U username -d database -w -c "select * from foo;"trabalho.
Steve Shipway
21

Isso pode ser feito criando um .pgpassarquivo no diretório inicial do Usuário (Linux). .pgpass formato de arquivo:

<databaseip>:<port>:<databasename>:<dbusername>:<password>

Você também pode usar curinga *no lugar dos detalhes.

Digamos que eu queira executar tmp.sqlsem solicitar uma senha.

Com o seguinte código, você pode no arquivo * .sh

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 `        
Srini
fonte
11
Qual é o sentido do eco "` chmod 0600 $ HOME / .pgpass `"? Que tal apenas chmod 0600 $ HOME / .pgpass?
Vlad Patryshev
12

Uma alternativa ao uso da PGPASSWORDvariável de ambiente é usar a conninfostring de acordo com a documentação :

Uma maneira alternativa de especificar parâmetros de conexão está em uma string conninfo ou em um URI, que é usado em vez de um nome de banco de dados. Esse mecanismo oferece amplo controle sobre a conexão.

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

postgres=>
ubi
fonte
obrigado, funcionou muito bem para mim
grepit
4

Adicionado conteúdo de pg_env.sh ao meu .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

com adição de (conforme sugestão do usuário4653174)

export PGPASSWORD='password'
Roubar
fonte