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


274

我如何调用psql以便不提示输入密码

这就是我所拥有的:

psql -Umyuser < myscript.sql

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


4
我最终选择了PGPASSWORD环境变量。这非常适合我的用例。该脚本简单而独立。
Axel Fontaine


Answers:


315

有几种向PostgreSQL进行身份验证的方法。您可能希望在https://www.postgresql.org/docs/current/static/client-authentication.html上研究密码验证的替代方法

要回答您的问题,有几种方法可以提供用于基于密码的身份验证的密码。最明显的方法是通过密码提示。取而代之的是,您可以在pgpass文件中或通过PGPASSWORD环境变量提供密码。看到这些:

没有选择将密码作为命令行参数提供的选项,因为该信息通常可供所有用户使用,因此不安全。但是,在Linux / Unix环境中,您可以为单个命令提供环境变量,如下所示:

PGPASSWORD=yourpass psql ...

11
我认为PGPASSWORD已过时,但仍然有效,顺便说一句。仅供参考
斯科特·马洛

35
是的,它已被弃用(并在链接之一中注明)。自从出现以来,可能还值得一提的是,反对使用折旧颇为激烈,因为它对许多人来说非常有用,但在某些情况下也可以使用而无需担心严重的安全问题。在我看来,这不比例如将.pgpass存储在NFS文件系统上更糟。我通常使用PGPASSWORD。
里斯(Reece)

1
命令行信息“可提供给所有用户”的想法是基于对多用户系统的过时假设,不适用于大多数现代环境,在这些现代环境中系统仅运行单个应用程序,并且都实现了自动化
Alex R,

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

1
这也适用于地形。您,我的朋友,是一位救命稻草
wildthing81 '19

67

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

set PGPASSWORD=[your password]

24
就我而言,set命令不起作用,但是export PGPASSWORD=[password]起作用了
CanKavaklıoğlu2013年

它在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
Govind Gupta

2
尝试不使用空格,例如。PGPASSWORD=password
阿里让

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. 使用. ~/.bashrc或类似的方式获取您的bash个人资料。
  5. 在命令行中输入别名。

请注意,如果您设置了导出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

2
Postrgres 9.3忽略环境变量PGPASSWORD
david.perez,

14

如果您在像我这样的Windows上遇到问题(我使用的是Windows 7 64位系统),则set PGPASSWORD=[Password]无法正常工作。

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

export PGPASSWORD=[password]

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

当然可以在Windows上使用:)


1
export PGPASSWORD=[password]使用命令行(cmd.exe)根本不适合我。您确定您没有使用cygwin或类似工具吗?
Devin Snyder 2014年

仅适用于cl,您将其添加到文件中了吗?现在只需将其键入命令?
Jamie Hutber

可以在linux / mac环境中使用它,对于Windows,我认为您应该找到一种导出此环境变量的方法。
Pengfei.X 2015年

因此,添加一个全局密码...那也是一个有趣的想法
Jamie Hutber


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

该方法的一个有效示例出现在stackoverflow.com/a/40614592/3696363中 -此问题的另一个答案。
Eliyahu Skoczylas

尽管该用户并没有真正要求我寻找相同的东西,但我会说这种方法不匹配。使用PGPASSFILE = <(无论如何)语法时,您可以执行解密文件之类的操作,并且仅将其存在于创建的文件描述符中。通过编写临时文件,您根本无法解决具有凭据的磁盘上文件的问题。处理像这样的任意行业规则并不是一件有趣的事情,但这是许多人要处理的事情。
Desidero

7

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

PGPASSWORD=password psql -U myuser < myscript.sql


5

对于那些不熟悉* nix shell脚本的人,以maybybyte的答案为基础,这是一个有效的脚本:

#!/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号附加到文件名,因此该脚本可以多次运行,甚至同时运行,而不会产生副作用。

请注意chmod在第4行使用命令-就像mayybyte描述的“ 不是普通文件 ”错误一样,如果不执行此操作,也会出现“ 权限 ”错误。

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

psql mydb jdoe

不要忘了使脚本可执行

chmod +x runpsql或您所说的脚本文件

更新:

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


4
您可以mktemp用来创建临时文件,而不必使用自己的命名方案。它会创建一个新的临时文件(/tmp/tmp.ITXUNYgiNh在Linux和/var/folders/xx/7gws2yy91vn9_t2lb8jcr2gr0000gn/T/tmp.QmbVOQk4MacOS X中都命名为类似文件),并将其名称打印到stdout。
伊万·科尔米切克

1
安全问题最好chmod 600在创建文件之后但在将密码写入文件之前执行以下操作。如所写,服务器上的恶意脚本可能会不断尝试读取这种格式的文件,有时会成功获取密码。另外,如果该脚本由于某种原因被中断,该文件将保留在磁盘上-编写shell trap处理程序将解决此问题。鉴于编写这样的安全脚本并非易事,我建议export PGPASSWORD改为使用。
RichVel19年

感谢@RichVel指出了这个小的安全漏洞。在输入密码之前,先触摸创建文件并将其设为私有,这无疑是一项改进。因为PGPASSWORD在9.3中已弃用,所以需要这种解决方案。
Eliyahu Skoczylas

一些文档说它已被弃用,但正如在此问答中的评论中所提到,该弃用已引起争议,它仍可从Postgres 10.6
RichVel 19'Apr

5

使用PGPASSWORD环境变量的一种替代方法是conninfo根据文档使用字符串

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

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

postgres=>



-1

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


-6

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.