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

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

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

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

【问题讨论】:

标签: postgresql bash command-line psql


【解决方案1】:

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

有几个选项:

  1. 在 pgpass 文件中设置它。 link
  1. 设置一个环境变量并从那里获取它:

    export PGPASSWORD='password'

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

    psql -h clustername -U username -d testdb

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

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

  3. 通过 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 显然你可以:stackoverflow.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 上:

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

      2. 运行命令: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 怎么样?
      猜你喜欢
      • 1970-01-01
      • 2013-03-22
      • 2020-07-04
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多