You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python subprocess stdin传递PostgreSQL密码失败问题求助

解决pg_dump通过stdin传递密码失败的问题

我懂你现在的困扰——明明用popen.stdin.write()把密码写进去了,pg_dump就是不买账,对吧?这其实是因为pg_dump默认不会从标准输入读取密码,它优先找终端交互,或者用环境变量、pgpass配置文件这些方式来获取密码。

为什么你的原代码不生效?

pg_dump的密码输入逻辑是和终端(tty)绑定的,不是普通的标准输入流。所以哪怕你通过stdin.write()把密码传进去,它也不会读取这部分内容,还是会等着从终端输入,这就是为什么你的代码没效果。

可行的解决方案

1. 使用PGPASSWORD环境变量(快速临时方案)

你可以把密码放到PGPASSWORD环境变量里,pg_dump会自动读取这个变量的值作为密码。这种方式不用改太多代码,适合临时测试:

import gzip
import subprocess
import os

# 复制系统原有环境变量,避免破坏其他配置
env_vars = os.environ.copy()
# 添加PGPASSWORD变量
env_vars['PGPASSWORD'] = 'rootVidhyaDhan123#!'

with gzip.open('backup.gz', 'wb') as f:
    popen = subprocess.Popen(
        ['pg_dump', '--no-owner', '--no-acl', '-U', 'postgres', '-d', 'database_name', '-h', '178.111.11.111'],
        stdout=subprocess.PIPE,
        universal_newlines=True,
        env=env_vars  # 传入带密码的环境变量
    )
    # 不需要sleep和stdin.write了
    for stdout_line in iter(popen.stdout.readline, ""):
        f.write(stdout_line.encode('utf-8'))
    popen.stdout.close()
    popen.wait()

2. 使用.pgpass配置文件(推荐,更安全)

硬编码密码在脚本里不安全,推荐用PostgreSQL的pgpass文件来管理密码,这样脚本里完全不用出现密码:

  • 创建pgpass文件:

    • Linux/macOS:在用户主目录下创建.pgpass文件,内容格式为:
      178.111.11.111:5432:database_name:postgres:rootVidhyaDhan123#!
      
      格式说明:主机名:端口:数据库名:用户名:密码(端口默认5432,如果你改了就填实际端口)
    • Windows:在%APPDATA%\postgresql目录下创建pgpass.conf文件,内容格式和上面一样。
  • 设置文件权限(仅Linux/macOS需要):
    必须把文件权限设为600,确保只有你自己能读取:

    chmod 600 ~/.pgpass
    
  • 修改后的脚本:
    现在脚本里不用处理密码了,直接运行pg_dump即可,它会自动读取pgpass文件的内容:

    import gzip
    import subprocess
    
    with gzip.open('backup.gz', 'wb') as f:
        popen = subprocess.Popen(
            ['pg_dump', '--no-owner', '--no-acl', '-U', 'postgres', '-d', 'database_name', '-h', '178.111.11.111'],
            stdout=subprocess.PIPE,
            universal_newlines=True
        )
        for stdout_line in iter(popen.stdout.readline, ""):
            f.write(stdout_line.encode('utf-8'))
        popen.stdout.close()
        popen.wait()
    

总结

  • 临时用脚本测试的话,用PGPASSWORD环境变量最快;
  • 长期使用的话,强烈推荐pgpass文件,既安全又不用在脚本里暴露密码。

内容的提问来源于stack exchange,提问作者Jinto Antony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:37:36