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

Posted

技术标签:

【中文标题】如何以非交互方式为“psql”指定密码?【英文标题】:How do I specify a password to 'psql' non-interactively? 【发布时间】:2011-09-18 07:22:36 【问题描述】:

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

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

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

【问题讨论】:

您可以使用连接网址。在***.com/questions/3582552/postgres-connection-url 中查看此答案。 @paulodiovani 我只想补充一点,这没有其他选项可以工作 - 只是 psql 谢谢。 【参考方案1】:

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

有几个选项:

    在 pgpass 文件中设置它。 link

    设置一个环境变量并从那里获取它:

    export PGPASSWORD='password'

    然后运行你的 psql 登录,甚至运行命令 那里:

    psql -h clustername -U username -d testdb

    在 Windows 上,您必须使用“set”:

    set PGPASSWORD=pass 然后登录到 psql bash。

    通过 URL 和环境变量传递它:

    psql "postgresql://$USER_NAME:$PASSWORD@$HOST_NAME/$DB_NAME"

【讨论】:

【参考方案2】:

在调用 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) 将其显示在 all 系统的用户(例如ps -ef)和2) 会将其添加到您的shell 的历史文件中(例如.bash_history)。我的建议是将密码存储在一个安全的文件中(例如,使用操作系统级别的权限来限制访问)然后PGPASSWORD=$(cat /<path>/to/secret.txt) ...【参考方案3】:

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

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

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

postgres=>

【讨论】:

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

我倾向于将 URL 传递给 psql:

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

这让我可以随意命名我的环境变量,并避免创建不必要的文件。

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

【讨论】:

你能在 pg_restore 中使用类似的东西吗?谢谢! @ccalderon911217 显然你可以:***.com/a/28359470/1388292 @JacquesGaudin 是的,我测试了自己!谢谢!【参考方案5】:

将 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'

【讨论】:

【参考方案6】:

在 Windows 上:

    为 PGPASSWORD 赋值:C:\&gt;set PGPASSWORD=pass

    运行命令:C:\&gt;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 表示 && 之前没有空格的评论 :)【参考方案7】:

来自official documentation:

拥有一个 ~/.pgpass 文件也很方便,以避免经常输入密码。请参阅Section 30.13 了解更多信息。

...

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

hostname:port:database:username:password

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

【讨论】:

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

一行:

export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command'

使用 command 一个 sql 命令,例如 "select * from schema.table"

或更具可读性:

export PGPASSWORD='password'
psql -h 'server name' -U 'user name' -d 'base name' \
     -c 'command' (eg. "select * from schema.table")

【讨论】:

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

这可以通过在 (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 怎么样?

以上是关于如何以非交互方式为“psql”指定密码?的主要内容,如果未能解决你的问题,请参考以下文章

如何以非交互方式分析 Java 应用程序?

如何以非交互方式在 Git 中重新排序提交

Spring如何以非阻塞方式匹配bcrypt密码

使用 git 以非交互方式编辑旧提交

以非交互方式执行 rgrep

如何向PostgreSQL导入sql文件