Postgresql: сценарий выполнения psql с паролем

274

Как я могу вызвать psql, чтобы он не запрашивал пароль ?

Вот что у меня есть:

psql -Umyuser < myscript.sql

Однако я не смог найти аргумент, который передает пароль, и поэтому psql всегда запрашивает его.

Аксель Фонтейн
источник
4
В итоге я выбрал переменную окружения PGPASSWORD. Это идеально подошло для моего использования. Простой и автономный в сценарии.
Аксель Фонтейн
Только что нашел этот postgresguide.com/utilities/psql.html
D_C
Возможный дубликат Как мне указать пароль для psql неинтерактивно?
Хелдер Перейра

Ответы:

315

Есть несколько способов аутентификации в PostgreSQL. Вы можете изучить альтернативы аутентификации по паролю на странице https://www.postgresql.org/docs/current/static/client-authentication.html .

Чтобы ответить на ваш вопрос, есть несколько способов предоставить пароль для аутентификации на основе пароля. Очевидный способ - через приглашение пароля. Вместо этого вы можете указать пароль в файле pgpass или через PGPASSWORDпеременную окружения. Смотрите эти:

Невозможно предоставить пароль в качестве аргумента командной строки, поскольку эта информация часто доступна всем пользователям и поэтому небезопасна. Однако в средах Linux / Unix вы можете предоставить переменную среды для одной команды, например:

PGPASSWORD=yourpass psql ...
Reece
источник
11
Я думаю, что PGPASSWORD устарела, но все еще работает, кстати. Просто к вашему сведению
Скотт Марлоу
35
Да, это устарело (и так отмечено в одной из ссылок). Так как это подходит, вероятно, также стоит отметить, что обесценивание горячо оспаривается, потому что это чрезвычайно полезно для многих людей, но может использоваться в некоторых обстоятельствах без серьезных проблем безопасности. Мне кажется, что это не хуже, чем хранить .pgpass в файловой системе NFS, например. Я использую PGPASSWORD регулярно.
Рис
1
идея о том, что информация командной строки «доступна для всех пользователей», основана на устаревших предположениях о многопользовательских системах и не применяется в большинстве современных сред, где системы просто запускают одно приложение и все автоматизировано
Alex R
159
PGPASSWORD=[your password] psql -Umyuser < myscript.sql
Greg
источник
1
это работает и в terraform. ты, мой друг, спасатель
wildthing81
67

Вы можете добавить эту командную строку в начале вашего скрипта:

set PGPASSWORD=[your password]
jbaylina
источник
24
в моем случае команда set не работала, но export PGPASSWORD=[password]работала
Can Kavaklıoğlu
это не работает в сценарии оболочки. Я использую это #!/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
Говинд Гупта
2
Попробуйте не использовать пробелы, например. PGPASSWORD=password,
Ariejan
48

Если вы намереваетесь использовать несколько соединений между хостами и базами данных, лучше всего использовать файл ~ / .pgpass .

шаги:

  1. Создайте файл, используя vim ~/.pgpassили аналогичный. Введите вашу информацию в следующем формате: hostname:port:database:username:passwordне добавляйте строковые кавычки вокруг значений вашего поля. Вы также можете использовать * в качестве подстановочного знака для полей порта / базы данных.
  2. Вы должны chmod 0600 ~/.pgpassсделать так, чтобы psql не игнорировал это молча.
  3. Создайте псевдоним в вашем профиле bash, который запускает вашу команду psql. Например: alias postygresy='psql --host hostname database_name -U username'значения должны соответствовать тем, которые вы ввели в файл ~ / .pgpass.
  4. Источник ваш профиль Bash с . ~/.bashrcили аналогичными.
  5. Введите свой псевдоним из командной строки.

Обратите внимание, что если у вас установлена ​​переменная export PGPASSWORD = '', она будет иметь приоритет над файлом.

Тэнди
источник
1
Вы должны сделать chmod 600файл, иначе он psqlбудет игнорироваться (в соответствии с документами).
RichVel
33

Это может быть старый вопрос, но есть альтернативный метод, который вы можете использовать, который никто не упомянул. Можно указать пароль непосредственно в URI подключения. Документация может быть найдена здесь , или здесь .

Вы можете указать свое имя пользователя и пароль непосредственно в URI соединения, предоставленного psql:

# postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
psql postgresql://username:password@localhost:5432/mydb
ajxs
источник
2
Postrgres 9.3 игнорирует переменную окруженияPGPASSWORD
david.perez
14

Если у вас проблемы с Windows, как я (я использую Windows 7 64-разрядная версия) и set PGPASSWORD=[Password]не работает.

Затем, как сказал Каваклиоглу в одном из комментариев,

export PGPASSWORD=[password]

Вам нужно будет сохранить это в верхней части файла или перед любым использованием, чтобы его установить перед вызовом.

Конечно, работает на окнах :)

Джейми Хатбер
источник
1
export PGPASSWORD=[password]у меня вообще не работает с использованием командной строки (cmd.exe). Вы уверены, что не использовали Cygwin или что-то подобное?
Девин Снайдер
Работает только с cl, вы добавили его в файл правильно? Теперь просто введите его в команду?
Джейми Хатбер
Это нормально использовать в среде Linux / Mac, для Windows, я думаю, вы должны найти способ экспортировать эту переменную среды.
Pengfei.X
Так что добавьте глобальный пароль ... Это тоже интересная идея
Джейми Хатбер,
7

Учитывая проблемы безопасности при использовании переменной среды PGPASSWORD, я думаю, что лучшее общее решение заключается в следующем:

  1. Напишите свой временный файл pgpass с паролем, который вы хотите использовать.
  2. Используйте переменную окружения PGPASSFILE, чтобы указать psql использовать этот файл.
  3. Удалить временный файл pgpass

Здесь есть пара замечаний. Шаг 1 предназначен для того, чтобы избежать попадания в пользовательский файл ~ / .pgpass, который может существовать. Вы также должны убедиться, что файл имеет разрешения 0600 или меньше.

Некоторые предлагают использовать bash, чтобы сократить это следующим образом:

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

При этом используется синтаксис <(), чтобы избежать необходимости записи данных в фактический файл. Но это не работает, потому что psql проверяет, какой файл используется, и выдаст ошибку, подобную этой:

WARNING: password file "/dev/fd/63" is not a plain file
mightybyte
источник
Рабочий пример такого подхода представлен в stackoverflow.com/a/40614592/3696363 - еще один ответ на этот вопрос.
Элиягу Скочилас
Хотя этот пользователь на самом деле не просил то же самое, что я ищу, я бы сказал, что подход не совпадает. При использовании синтаксиса PGPASSFILE = <(что угодно) вы можете делать такие вещи, как дешифрование файла, и он должен присутствовать только в созданном дескрипторе файла. Записывая временный файл, вы принципиально не решаете проблему наличия файла на диске с учетными данными. Нелегко иметь дело с произвольными подобными отраслевыми правилами, но с этим сталкиваются многие люди.
Desidero
7

Это можно сделать просто используя PGPASSWORD. Я использую PSQL 9.5.10. В вашем случае решение будет

PGPASSWORD=password psql -U myuser < myscript.sql

pyAddict
источник
5

Основываясь на ответе mightybyte для тех, кто не знаком с сценариями * nix shell, вот рабочий сценарий:

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

Двойной знак доллара ( $$) в /tmp/pgpasswd$$строке 2 добавляет идентификационный номер процесса к имени файла, так что этот сценарий можно запускать несколько раз, даже одновременно, без побочных эффектов.

Обратите внимание на использование chmodкоманды в строке 4 - точно так же, как и в случае ошибки « not plain file », описанной в mightybyte , также есть ошибка « permissions », если это не сделано.

В строке 7 вам не нужно будет использовать -hфлаг myserver , -pmyport или -Ujdoe, если вы используете значения по умолчанию ( localhost : 5432 ) и имеете только одного пользователя базы данных. Для нескольких пользователей (но подключение по умолчанию) измените эту строку на

psql mydb jdoe

Не забудьте сделать скрипт исполняемым с

chmod +x runpsql( или как вы назвали файл скрипта )

ОБНОВИТЬ:

Я воспользовался советом RichVel и сделал файл нечитаемым, прежде чем вводить в него пароль. Это закрывает небольшую дыру в безопасности. Спасибо!

Элиягу Скочилас
источник
4
Вы можете использовать mktempдля создания временного файла вместо того, чтобы придумать свою собственную схему именования. Он создает новый временный файл (названный как-то как /tmp/tmp.ITXUNYgiNhв Linux и /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4в MacOS X) и выводит его имя на стандартный вывод.
Иван Колмычек
1
Проблема безопасности Лучше всего это сделать chmod 600после создания файла, но перед тем, как записать в него пароль. Как написано, вредоносный скрипт на сервере может постоянно пытаться читать файлы этого формата, и иногда ему удается получить пароль. Кроме того, если этот сценарий по какой-то причине прервется, файл останется на диске - запись trapобработчика оболочки решит эту проблему. Учитывая, что написать такой безопасный сценарий нетривиально, я рекомендую использовать export PGPASSWORDвместо него.
RichVel
Спасибо, @RichVel за то, что указал на эту маленькую дыру в безопасности. Коснитесь создания и сделав файл приватным, прежде чем вводить в него пароль, - это определенное улучшение. Такое решение необходимо, потому PGPASSWORDчто устарело в 9.3.
Элиягу Скочилас
В некоторых документах говорится, что это устарело, но, как уже упоминалось в комментарии к этому вопросу, оспаривание оспаривается, и оно все еще работает с Postgres 10.6
RichVel
5

Альтернативой использованию PGPASSWORDпеременной среды является использование conninfoстроки в соответствии с документацией

Альтернативный способ указать параметры соединения - это строка conninfo или URI, который используется вместо имени базы данных. Этот механизм дает вам очень широкий контроль над соединением.

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

postgres=>
уби
источник
1

8 лет спустя ...

На моем Mac я должен был вставить строку в файл, ~/.pgpassкак:

<IP>:<PORT>:<dbname>:<user>:<password>

Также смотрите:
https://www.postgresql.org/docs/current/libpq-pgpass.html
https://wiki.postgresql.org/wiki/Pgpass

Дирк Шумахер
источник
Не используйте -W для PSQL, если вы используете .pgpass. Этот параметр отменяет использование .pgpass.
Аввенсис
-1

Я обнаружил, что psql показывает пароль, даже если вы определяете переменную PGPASSWORD, но вы можете указать опцию -w для psql, чтобы пропустить запрос пароля.

Марк Локшин
источник
-6

Используйте -w в команде: psql -h localhost -p 5432 -U пользователь -w

vjOnstack
источник