ChatGPT解决这个技术问题 Extra ChatGPT

Postgresql:使用密码编写 psql 执行脚本

如何调用 psql 使其不提示输入密码?

这就是我所拥有的:

psql -Umyuser < myscript.sql

但是,我找不到传递密码的参数,因此 psql 总是提示输入密码。

我最终选择了 PGPASSWORD 环境变量。这非常适合我的用例。脚本中简单且独立。

R
Reece

您可能希望阅读 the ways to authenticate to PostgreSQL 的摘要。

要回答您的问题,有几种方法可以为基于密码的身份验证提供密码:

通过密码提示。示例:psql -h uta.biocommons.org -U foo 用户 foo 的密码:在 pgpass 文件中。请参阅 libpq-pgpass。格式::::: 带有 PGPASSWORD 环境变量。请参阅 libpq-envars。示例:export PGPASSWORD=yourpass psql ... # 或仅用于此调用的一行:PGPASSWORD=yourpass psql ... 在连接字符串中 密码和其他选项可以在连接字符串/URI 中指定。请参阅 app-psql。示例:psql postgresql://username:password@dbmaster:5433/mydb?sslmode=require


我认为 PGPASSWORD 已被弃用但仍然有效,顺便说一句。仅供参考
是的,它已被弃用(并在其中一个链接中注明)。自从它出现以来,可能还值得注意的是,弃用受到了激烈的争论,因为它对许多人来说非常有用,但可以在某些情况下使用,而不会产生严重的安全问题。例如,在我看来,这并不比将 .pgpass 存储在 NFS 文件系统上更糟糕。我经常使用 PGPASSWORD。
命令行信息“对所有用户可用”的想法是基于关于多用户系统的过时假设,不适用于大多数现代环境中系统只运行单个应用程序并且全部自动化
快进 2021:对于使用 Postgresql 版本 13 的任何人 - PGPASSWORD=yourpass psql ... 似乎不再适用于版本 13(在我的情况下是 Debian 10),因此我成功地使用了 official docs 中解释的连接字符串
为我工作。 psql (PostgreSQL) 13.2 在 Mac 上。
G
Greg
PGPASSWORD=[your password] psql -Umyuser < myscript.sql

这也适用于 terraform。你,我的朋友,是救生员
E
Eduardo Cuomo

您可以在脚本的开头添加此命令行:

export PGPASSWORD="[your password]"

在我的情况下,set 命令不起作用,但 export PGPASSWORD=[password] 确实起作用
它在 shell 脚本中不起作用。我正在使用它#!/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
尽量不要使用空格,例如。 PGPASSWORD=password
a
ajxs

这可能是一个老问题,但是您可以使用另一种没有人提到的方法。可以直接在连接 URI 中指定密码。可以在 herehere 中找到该文档。

您可以直接在提供给 psql 的连接 URI 中提供您的用户名和密码:

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

Postrgres 9.3 忽略环境变量 PGPASSWORD
它可能需要引用参数才能工作:psql.exe "postgresql://username:password@address:5432/database"
e
enharmonic

如果您打算拥有多个主机/数据库连接,则 ~/.pgpass file 是可行的方法。

脚步:

使用 vim ~/.pgpass 或类似方法创建文件。请按以下格式输入您的信息:hostname:port:database:username:password 不要在字段值周围添加字符串引号。您还可以使用 * 作为端口/数据库字段的通配符。您必须 chmod 0600 ~/.pgpass 以使其不会被 psql 静默忽略。在您的 bash 配置文件中创建一个别名,为您运行 psql 命令。例如:alias postygresy='psql --host hostname database_name -U username' 这些值应该与您输入到 ~/.pgpass 文件的值相匹配。使用 获取您的 bash 配置文件。 ~/.bashrc 或类似的。从命令行键入您的别名。

请注意,如果您设置了 export PGPASSWORD='' 变量,它将优先于文件。


您必须对文件执行 chmod 600,否则 psql 会默默地忽略它(根据文档)。
在 Windows 服务器上,这可能不是一个很好的解决方案,在 Windows 服务器上,许多事情都是在没有用户目录的情况下与用户一起运行的。
u
ubi

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

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

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

postgres=>

这对于其他方法不起作用的健全性测试很有用。此外,将密码从您的 shell 历史记录中删除可以像 putting a space before a command 一样简单。
F
Femi

您必须创建密码文件:有关详细信息,请参阅 http://www.postgresql.org/docs/9.0/interactive/libpq-pgpass.html


J
Jamie Hutber

如果您在像我这样的 Windows 上遇到问题(我使用的是 Windows 7 64 位)并且 set PGPASSWORD=[Password] 不起作用。

然后,正如 Kavaklioglu 在其中一条评论中所说,

export PGPASSWORD=[password]

您需要将其保存在文件顶部,或在任何使用之前保存,以便在调用之前对其进行设置。

当然可以在 Windows 上工作:)


export PGPASSWORD=[password] 对我使用命令行 (cmd.exe) 根本不起作用。你确定你没有使用cygwin或类似的东西吗?
仅适用于 cl,您将其添加到文件中对吗?现在只是将它输入到命令中?
在 linux/mac 环境中使用它是可以的,对于 windows,我认为你应该找到一种方法来导出这个环境变量。
所以添加一个全局密码......这也是一个有趣的想法
m
mightybyte

考虑到使用 PGPASSWORD 环境变量的安全问题,我认为最好的整体解决方案如下:

使用您要使用的密码编写您自己的临时 pgpass 文件。使用 PGPASSFILE 环境变量告诉 psql 使用该文件。删除临时 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

此方法的一个工作示例出现在 stackoverflow.com/a/40614592/3696363 - 此问题的另一个答案中。
尽管该用户并没有真正要求我要寻找的东西,但我会说这种方法不匹配。使用 PGPASSFILE=<(whatever) 语法时,您可以执行诸如解密文件之类的操作,并且仅将其存在于创建的文件描述符中。通过编写一个临时文件,您并没有从根本上解决在磁盘上拥有一个带有凭据的文件的问题。处理这样的任意行业规则并不好玩,但这是很多人处理的事情。
T
Taher Khorshidi

只需使用 PGPASSWORD 即可完成。我正在使用 psql 9.5.10。在您的情况下,解决方案是

PGPASSWORD=password psql -U myuser < myscript.sql


E
Eliyahu Skoczylas

对于那些不熟悉 *nix shell 脚本的人来说,在 mightybyte's answer 的基础上构建了一个工作脚本:

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

第 2 行 /tmp/pgpasswd$$ 中的双美元符号 ($$) 将进程 ID 号附加到文件名,因此该脚本可以多次运行,甚至同时运行,而不会产生副作用。

请注意在第 4 行使用 chmod 命令 - 就像 mightybyte 描述的“not a plain file”错误一样,还有一个“permissions< /em>" 错误,如果不这样做。

在第 7 行,您不必使用 -hmyserver-pmyport-Ujdoe 标志如果您使用默认值 (localhost : 5432) 并且只有一个数据库用户。对于多个用户,(但默认连接)将该行更改为

psql mydb jdoe

不要忘记使脚本可执行

chmod +x runpsql (或任何你调用的脚本文件)

更新:

在输入密码之前,我接受了 RichVel 的建议并使文件不可读。这关闭了一个轻微的安全漏洞。谢谢!


您可以使用 mktemp 创建一个临时文件,而不是提出自己的命名方案。它创建一个新的临时文件(在 Linux 中命名为 /tmp/tmp.ITXUNYgiNh,在 MacOS X 中命名为 /var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4)并将其名称打印到标准输出。
安全问题 最好在创建文件之后但在将密码写入文件之前执行 chmod 600。如前所述,服务器上的恶意脚本可能会不断尝试读取这种格式的文件,并且有时会成功获取密码。此外,如果此脚本由于某种原因被中断,文件将留在磁盘上 - 编写 shell trap 处理程序将解决此问题。鉴于编写这样的安全脚本并非易事,我建议改用 export PGPASSWORD
谢谢,@RichVel 指出了那个小的安全漏洞。在输入密码之前触摸创建文件并将其设为私有是一个明显的改进。需要这种解决方案,因为 PGPASSWORD 在 9.3 中已被弃用。
一些文档说它已被弃用,但正如 this Q&A 中的评论中提到的,弃用是有争议的,它仍然适用于 Postgres 10.6
在您的主目录 mkdir ~/.creds 中创建文件;触摸 ~/.creds/pgpass$$ && chmod 0600 ~/.creds/pgpass$$
D
Dirk Schumacher

8年后...

在我的 Mac 上,我必须在文件 ~/.pgpass 中添加一行,例如:

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

另请参阅:
https://www.postgresql.org/docs/current/libpq-pgpass.html
https://wiki.postgresql.org/wiki/Pgpass


如果您使用 .pgpass,请不要将 -W 用于 psql。此参数取消 .pgpass 的使用。
还要确保该文件的权限 u=rw
s
shane

这也适用于其他 postgresql cli,例如您可以在非交互模式下运行 pgbench。

export PGPASSWORD=yourpassword
/usr/pgsql-9.5/bin/pgbench -h $REMOTE_PG_HOST -p 5432 -U postgres -c 12 -j 4 -t 10000 example > pgbench.out 2>&1 &

M
Mark Lokshin

我发现,即使您定义了 PGPASSWORD 变量,psql 也会显示密码提示,但是您可以为 psql 指定 -w 选项以省略密码提示。


v
vjOnstack

在命令中使用 -w: psql -h localhost -p 5432 -U user -w