如何以非交互方式为“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如果在一个答案中添加大多数选项还为时不晚:
有几个选项:
-
在 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:\>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 表示 && 之前没有空格的评论 :)【参考方案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”指定密码?的主要内容,如果未能解决你的问题,请参考以下文章