Postgresql: Criando scripts de execução psql com senha


274

Como posso chamar o psql para que ele não solicite uma senha ?

Isto é o que eu tenho:

psql -Umyuser < myscript.sql

No entanto, não consegui encontrar o argumento que passa a senha e, portanto, o psql sempre solicita isso.


4
Acabei indo para a variável de ambiente PGPASSWORD. Isso encaixou perfeitamente no meu caso. Simples e independente no script.
— Axel Fontaine

Acabei de encontrar este postgresguide.com/utilities/psql.html
— D_C

Respostas:


315

Existem várias maneiras de autenticar no PostgreSQL. Você pode investigar alternativas à autenticação de senha em https://www.postgresql.org/docs/current/static/client-authentication.html .

Para responder à sua pergunta, existem algumas maneiras de fornecer uma senha para autenticação baseada em senha. A maneira óbvia é através do prompt de senha. Em vez disso, você pode fornecer a senha em um arquivo pgpass ou através da PGPASSWORDvariável de ambiente. Veja estes:

Não há opção para fornecer a senha como um argumento de linha de comando, porque essas informações geralmente estão disponíveis para todos os usuários e, portanto, inseguras. No entanto, em ambientes Linux / Unix, você pode fornecer uma variável de ambiente para um único comando como este:

PGPASSWORD=yourpass psql ...

11
Eu acho que PGPASSWORD está obsoleto, mas ainda funciona, btw. Apenas FYI
— Scott Marlowe

35
Sim, está obsoleto (e observado em um dos links). Desde que surgiu, provavelmente também vale a pena notar que a depreciação é muito contestada, porque é extremamente útil para muitas pessoas e ainda pode ser usada em algumas circunstâncias sem sérias preocupações de segurança. Parece-me que não é pior do que armazenar .pgpass em um sistema de arquivos NFS, por exemplo. Eu uso PGPASSWORD rotineiramente.
— Reece

1
a ideia de que as informações de linha de comando é "disponível para todos os usuários" se baseia em pressupostos antiquados sobre sistemas multi-utilizador e não se aplica na maioria dos ambientes modernos onde os sistemas basta executar uma única aplicação e é tudo automatizado
— Alex R

159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql

1
isso funciona também em terraform. Você, meu amigo, é um salva-vidas
— wildthing81

67

Você pode adicionar esta linha de comando no início do seu script:

set PGPASSWORD=[your password]

24
no meu comando caso conjunto não funcionou, mas export PGPASSWORD=[password]fez trabalho
— Can Kavaklıoğlu

não funciona no shell script. Estou usando #!/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
Tente não usar espaços, por exemplo. PGPASSWORD=password.
— Ariejan 29/11

48

Se você pretende ter vários hosts / conexões com o banco de dados, o arquivo ~ / .pgpass é o caminho a seguir.

Passos:

  1. Crie o arquivo usando vim ~/.pgpassou similar. Insira suas informações no seguinte formato: hostname:port:database:username:passwordNão adicione aspas em torno dos valores do seu campo. Você também pode usar * como um curinga para seus campos de porta / banco de dados.
  2. Você deve chmod 0600 ~/.pgpass, para que não seja ignorado silenciosamente pelo psql.
  3. Crie um alias no seu perfil do bash que execute seu comando psql para você. Por exemplo: alias postygresy='psql --host hostname database_name -U username'Os valores devem corresponder aos que você inseriu no arquivo ~ / .pgpass.
  4. Crie seu perfil do bash com . ~/.bashrcou similar.
  5. Digite seu alias na linha de comando.

Observe que se você tiver um conjunto de variáveis ​​PGPASSWORD = '' de exportação, ele terá precedência sobre o arquivo.


1
Você deve fazer um chmod 600no arquivo, caso contrário psqlo ignorará silenciosamente (de acordo com os documentos).
— 19419 RichVel

33

Essa pode ser uma pergunta antiga, mas há um método alternativo que você pode usar e que ninguém mencionou. É possível especificar a senha diretamente no URI da conexão. A documentação pode ser encontrada aqui , ou aqui .

Você pode fornecer seu nome de usuário e senha diretamente no URI de conexão fornecido para psql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb

2
Postrgres 9.3 ignora variável de ambientePGPASSWORD
— david.perez 27/03

14

Se você está tendo problemas no Windows como eu (estou usando o Windows 7 de 64 bits) e set PGPASSWORD=[Password]não funcionou.

Então, como Kavaklioglu disse em um dos comentários,

export PGPASSWORD=[password]

Você precisará salvá-lo na parte superior do arquivo ou antes de qualquer uso, para que seja definido antes de ser chamado.

Certamente funciona no Windows :)


1
export PGPASSWORD=[password]não funciona para mim usando a linha de comando (cmd.exe). Tem certeza de que não estava usando o cygwin ou algo semelhante?
— Devin Snyder

Só funciona com cl, você adicionou ao arquivo, certo? Agora, basta digitar no comando?
— 21714 Jamie Hutber #

tudo bem em usá-lo no ambiente linux / mac, para o windows, acho que você deve encontrar uma maneira de exportar essa variável de ambiente.
— Pengfei.X

Então adicione uma senha global ... Isso é uma idéia interessante, bem
— Jamie Hutber


7

Dadas as preocupações de segurança sobre o uso da variável de ambiente PGPASSWORD, acho que a melhor solução geral é a seguinte:

  1. Escreva seu próprio arquivo pgpass temporário com a senha que deseja usar.
  2. Use a variável de ambiente PGPASSFILE para dizer ao psql para usar esse arquivo.
  3. Remova o arquivo pgpass temporário

Há alguns pontos de nota aqui. A Etapa 1 existe para evitar a sujeira no arquivo ~ / .pgpass do usuário que possa existir. Você também deve garantir que o arquivo tenha permissões 0600 ou menos.

Alguns sugeriram aproveitar o bash para atalho da seguinte maneira:

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

Isso usa a sintaxe <() para evitar a necessidade de gravar os dados em um arquivo real. Mas não funciona porque o psql verifica qual arquivo está sendo usado e gera um erro como este:

WARNING: password file "/dev/fd/63" is not a plain file

Um exemplo de trabalho dessa abordagem aparece em stackoverflow.com/a/40614592/3696363 - outra resposta a esta pergunta.
— Eliyahu Skoczylas

Embora esse usuário não tenha realmente pedido a mesma coisa que estou procurando, diria que a abordagem não corresponde. Ao usar a sintaxe PGPASSFILE = <(qualquer que seja), é possível descriptografar um arquivo e apenas tê-lo presente no descritor de arquivo criado. Ao escrever um arquivo temporário, você não está resolvendo fundamentalmente o problema de ter um arquivo em disco com credenciais. Não é divertido lidar com regras arbitrárias da indústria como essa, mas é algo com o qual muitas pessoas lidam.
— Desidero 18/10

7

Isso pode ser feito simplesmente usando PGPASSWORD. Estou usando o psql 9.5.10. No seu caso, a solução seria

PGPASSWORD=password psql -U myuser < myscript.sql


5

Com base na resposta de mightybyte para aqueles que não se sentem confortáveis ​​com o script * nix shell, aqui está um script de trabalho:

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

O cifrão duplo ( $$) na /tmp/pgpasswd$$linha 2 anexa o número do ID do processo ao nome do arquivo, para que este script possa ser executado mais de uma vez, mesmo simultaneamente, sem efeitos colaterais.

Observe o uso do chmodcomando na linha 4 - assim como o erro " não é um arquivo simples " descrito por mightybyte , também há um erro " permissões " se isso não for feito.

Na linha 7, você não precisará usar o sinalizador -hmyserver , -pmyport ou -Ujdoe se usar os padrões ( localhost : 5432 ) e tiver apenas um usuário de banco de dados. Para vários usuários, (mas a conexão padrão) altere essa linha para

psql mydb jdoe

Não esqueça de tornar o script executável com

chmod +x runpsql( ou o que você chamou de arquivo de script )

ATUALIZAR:

Eu segui o conselho de RichVel e tornei o arquivo ilegível antes de colocar a senha nele. Isso fecha um pequeno furo de segurança. Obrigado!


4
Você pode usar mktemppara criar um arquivo temporário em vez de criar seu próprio esquema de nomenclatura. Ele cria um novo arquivo temporário (chamado algo como /tmp/tmp.ITXUNYgiNhno Linux e /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4no MacOS X) e imprime seu nome em stdout.
— Ivan Kolmychek

1
Problema de segurança É melhor fazer chmod 600depois de criar o arquivo, mas antes de gravar a senha nele. Conforme escrito, um script mal-intencionado no servidor poderia tentar continuamente ler arquivos desse formato e, às vezes, conseguiria obter a senha. Além disso, se esse script for interrompido por algum motivo, o arquivo será deixado no disco - a gravação de um trapmanipulador de shell resolveria isso. Dado que não é trivial escrever um script seguro como esse, recomendo o uso export PGPASSWORD.
— RichVel 18/02/19

Obrigado, @RichVel por apontar essa pequena falha de segurança. Toque em criar e tornar o arquivo privado antes de inserir a senha. É uma melhoria definitiva. Esse tipo de solução é necessário porque PGPASSWORDfoi descontinuado na 9.3.
— Eliyahu Skoczylas 11/04/19

Alguns dos docs dizer que é obsoleto, mas como mencionado em um comentário no este Q & A , a depreciação é contestada e ainda funciona como de Postgres 10.6
— RichVel

5

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 controle muito amplo sobre a conexão.

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

postgres=>



-1

Acho que o psql mostra o prompt de senha, mesmo que você defina a variável PGPASSWORD, mas você pode especificar a opção -w para o psql omitir o prompt de senha.


-6

Use -w no comando: psql -h localhost -p 5432 -U user -w

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.