ChatGPT解决这个技术问题 Extra ChatGPT

如何以非交互方式为“psql”指定密码?

我正在尝试使用 shell 脚本自动化数据库创建过程,而我在将密码传递给 psql 时遇到了障碍。下面是来自 shell 脚本的一些代码:

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

如何以非交互方式将密码传递给 psql

您可以使用连接网址。在 stackoverflow.com/questions/3582552/postgres-connection-url 中检查此答案。
@paulodiovani 我只想补充一点,这没有其他选项 - 只是 psql 谢谢。

r
rogerdpack

在调用 psql 之前在脚本中设置 PGPASSWORD 环境变量

PGPASSWORD=pass1234 psql -U MyUsername myDatabaseName

如需参考,请参阅http://www.postgresql.org/docs/current/static/libpq-envars.html

编辑

从 Postgres 9.2 开始,还可以选择指定可以包含用户名 密码的 connection string or URI。语法是:

$ psql postgresql://[user[:password]@][host][:port][,...][/dbname][?param1=value1&...]

使用它会带来安全风险,因为当其他用户使用 ps (Linux)、ProcessExplorer (Windows) 或类似工具查看正在运行的进程的命令行时,密码以纯文本形式可见。

另请参阅 Database Administrators 上的此问题


例如,在一行中,您可以执行以下操作:PGPASSWORD=pass1234 psql -u MyUsername myUserName
我认为这是简单地运行 SQL 脚本最方便的方法。
我只能添加 - 在命令行中第一个字符之前添加一个 space,并且该命令不会存储在 bash 历史记录中。适用于 ubuntu/bash。
奖励:适用于 Docker:docker run -e PGPASSWORD="$(pbpaste)" --rm postgres psql -h www.example.com dbname username -c 'SELECT * FROM table;'
对于那些即将使用它的人,请注意,将密码作为 shell 命令的一部分包含在 1) 将其显示在系统的 所有 用户可见的进程列表中(例如 ps -ef),而 2) 会将其添加到您的 shell 的历史文件中(例如 .bash_history)。我的建议是将密码存储在安全文件中(例如,使用操作系统级别的权限来限制访问)然后PGPASSWORD=$(cat /<path>/to/secret.txt) ...
r
rogerdpack

official documentation

拥有一个 ~/.pgpass 文件也很方便,以避免经常输入密码。有关详细信息,请参阅第 30.13 节。

...

该文件应包含以下格式的行:

hostname:port:database:username:password

将使用第一行中与当前连接参数匹配的密码字段。


谢谢,我知道 pgpass,但这并不能解决问题 - 我需要一个独立的 bash 脚本来操作数据库,因此我的问题是关于通过命令行将信息传递给 psql。
我认为您唯一的选择是设置您的 bash 脚本可以访问的 .pgpass 文件。或者根本不使用密码——您可以设置另一种身份验证形式,例如 ident,或使用 SSL 证书。
这就是我担心的:) 谢谢你的信息!
另一种选择可能是使用期望。但我真的很讨厌期望:)
不要忘记删除组和其他用户读取、写入、执行 .pgpass 文件的权限!运行 chmod go-rwx .pgpass
A
AdrieanKhisbe

一行:export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command' with command 一个 sql 命令,例如“select * from schema.table”

或更具可读性: export PGPASSWORD='password' psql -h 'server name' -U 'user name' -d 'base name' \ -c 'command' (例如“select * from schema.table”)


一行可以稍微简化为: PGPASSWORD='password' psql .... 这还具有在命令完成后无法访问变量的好处。
export PGPASSWORD=YourNewPassword 比其他变体更适合我。
export PGPASSWORD 听起来是个非常糟糕的主意
这会将密码保存在您的 bash 历史 ~/.bash_history 文件中(除非您总是小心地添加前面的空格),并将密码导出到您当前的环境 FWIW :|
无需导出 PGPASSWORD
P
Peter Mortensen

我倾向于将 URL 传递给 psql

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

这使我可以根据需要自由命名环境变量,并避免创建不必要的文件。

这需要 libpq。可以在 here 中找到该文档。


你可以在 pg_restore 中使用这样的东西吗?谢谢!
@ccalderon911217 显然你可以:stackoverflow.com/a/28359470/1388292
@JacquesGaudin 是的,我测试了自己!谢谢!
B
Brian Burns

在 Windows 上:

为 PGPASSWORD 赋值:C:\>set PGPASSWORD=pass 运行命令:C:\>psql -d database -U user

准备好

或者在一行中,

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

注意 && 之前没有空格!


我试过了,但它没有用。仍然被要求输入密码。
@antipattern 您还必须通过选项 -w
PGPASSWORD=xxxx psql -U username -d database -w -c "select * from foo;" 有效。
在 Powershell 中,您可以这样做:$env:PGPASSWORD=pass; psql -d database -U user
关于 && 之前没有空格的评论 +1000 :)
j
jonsca

这可以通过在 (Linux) 用户的主目录中创建一个 .pgpass 文件来完成。 .pgpass 文件格式:

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

您还可以使用通配符 * 代替详细信息。

假设我想在不提示输入密码的情况下运行 tmp.sql

使用以下代码,您可以在 *.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 `        

echo "` chmod 0600 $HOME/.pgpass `" 有什么意义? chmod 0600 $HOME/.pgpass 怎么样?
P
Peter Mortensen

使用 PGPASSWORD 环境变量的替代方法是根据 documentation 使用 conninfo 字符串:

指定连接参数的另一种方法是使用 conninfo 字符串或 URI,而不是数据库名称。这种机制使您可以非常广泛地控制连接。

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

postgres=>

我经常使用这种方法,因为它看起来更具可读性,但为了安全起见,在命令中包含密码并不是一个好主意,因为任何(非 root)用户都可以使用简单的 ps a 命令读取它
R
Raj Verma

如果在一个答案中添加大多数选项还为时不晚:

有几个选项:

在 pgpass 文件中设置它。关联

设置一个环境变量并从那里获取它:export PGPASSWORD='password' 然后运行你的 psql 登录,甚至从那里运行命令: psql -h clustername -U username -d testdb 在 Windows 上你必须使用“set " :设置 PGPASSWORD=pass 然后登录到 psql bash。通过 URL 和环境变量传递它: psql "postgresql://$USER_NAME:$PASSWORD@$HOST_NAME/$DB_NAME"


R
Rob

将 pg_env.sh 的内容添加到我的 .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

添加(根据 user4653174 建议)

export PGPASSWORD='password'

P
Promise Preston

只是为了增加更多的清晰度。

您可以将密码分配给 PGPASSWORD 变量。

因此,而不是下面这将要求您输入密码:

psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --password --dbname=postgres

我们将用 PGPASSWORD=QghyumjB3ZtCQkdf 替换 --password 标志。所以它将是:

PGPASSWORD=QghyumjB3ZtCQkdf psql --host=aurora-postgres.cluster-fgshdjdf.eu-west-1.rds.amazonaws.com --port=5432 --user=my_master_user --dbname=postgres

这样您就不需要输入密码。