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

Postgresql: Scripting psql execution with password

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

这就是我所拥有的:

1
psql -Umyuser < myscript.sql

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


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

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

  • https://www.postgresql.org/docs/9.0/static/libpq-pgpass.html网站
  • https://www.postgresql.org/docs/9.0/interactive/libpq-envars.html网站

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

1
PGPASSWORD=yourpass psql ...


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


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

1
SET PGPASSWORD=[your password]


如果您打算有多个主机/数据库连接,可以使用~/.pgpass文件。

步骤:

  • 使用vim ~/.pgpass或类似工具创建文件。按以下格式输入信息:hostname:port:database:username:password不在字段值周围添加字符串引号。您还可以使用*作为端口/数据库字段的通配符。
  • 为了不被psql悄悄地忽略,您必须使用ecx1(4)。
  • 在bash概要文件中创建一个别名,用于运行psql命令。例如:alias postygresy='psql --host hostname database_name -U username'值应该与输入~/.pgpass文件的值匹配。
  • 使用. ~/.bashrc或类似工具获取bash配置文件。
  • 从命令行键入别名。
  • 请注意,如果设置了export pgpassword=''变量,它将优先于文件。


    这可能是一个古老的问题,但有一种替代方法可以使用,但没有人提到过。可以直接在连接URI中指定密码。文档可以在这里找到,也可以在这里找到。

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

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


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


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

    然后,正如卡瓦克利奥卢在其中一条评论中所说,

    1
    export PGPASSWORD=[password]

    您将需要在文件顶部保存这个文件,或者在任何使用之前保存它,以便在被调用之前设置它。

    当然适用于Windows:)


    只需使用pgpassword就可以完成。我使用的是PSQL9.5.10。在你的情况下,解决办法是

    PGPASSWORD=password psql -U myuser < myscript.sql


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

  • 用要使用的密码编写自己的临时pgpass文件。
  • 使用pgpassfile环境变量告诉psql使用该文件。
  • 删除临时pgpass文件
  • 这里有几个要点。步骤1是为了避免弄脏用户可能存在的~/.pgpass文件。您还必须确保该文件具有0600或更低的权限。

    有些人建议利用bash来实现以下捷径:

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

    它使用<()语法来避免将数据写入实际文件。但它不起作用,因为psql会检查正在使用的文件,并引发如下错误:

    1
    WARNING: password file"/dev/fd/63" IS NOT a plain file


    基于对*nix shell脚本不满意的人的强大的回答,下面是一个工作脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    #!/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命令-就像可能描述的"非普通文件"错误一样,如果不这样做,也会出现"权限"错误。

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

    1
    psql mydb jdoe

    不要忘记使用

    chmod +x runpsql (or whatever you called the script file)

    更新:

    我接受了Richvel的建议,让文件在输入密码之前无法读取。这就封闭了一个小小的安全漏洞。谢谢!


    您可能会发现这很有用:windows psql命令行:是否有一种方法允许无密码登录?


    我发现,即使定义pgpassword变量,psql也会显示密码提示,但可以指定-w选项让psql忽略密码提示。


    在命令中使用-w:psql-h本地主机-p 5432-u用户-w