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

使用Python subprocess执行psql命令时出现“No such file or directory: psql”错误

问题

我在本地PostgreSQL实例上用以下命令可以正常列出所有数据库:

psql --host localhost --port 55000 --username postgres -At --command 'SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn ORDER BY datname;' postgres

但用Python subprocess执行时却报错:

FileNotFoundError: [Errno 2] No such file or directory: 'psql'

我的Python代码如下:

import subprocess
import shlex

source_host = "localhost"
source_port = "55000"
source_user = "postgres"
source_password = "postgrespw"
database_select_query = "SELECT datname FROM pg_database WHERE NOT datistemplate AND datallowconn ORDER BY datname;"

database_select_command = f"""
    psql \
        --host {source_host} \
        --port {source_port} \
        --username {source_user} \
        -At --command '{database_select_query}' \
    postgres
"""
print(database_select_command)
print(shlex.split(database_select_command))
output = subprocess.run(
    shlex.split(database_select_command),
    capture_output=True,
    shell=False,
    env={"PGPASSWORD": source_password},
)
print(output)

我试过转义引号、改成单行命令,问题还是没解决,到底忽略了什么?

解决方案

核心原因

subprocess执行命令时的环境变量PATH和你终端里的不一样——终端能找到psql是因为shell的PATH包含了PostgreSQL的bin目录,但Python脚本的执行环境没加载这个路径,导致系统找不到psql可执行文件。

具体解决办法

  • 使用psql的绝对路径
    先找到psql的完整安装路径(比如Linux下可能是/usr/bin/psql,macOS Homebrew安装的话是/usr/local/bin/psql,Windows下类似C:\Program Files\PostgreSQL\15\bin\psql.exe),把命令里的psql替换成绝对路径即可。
    示例修改:

    database_select_command = f"""
        /usr/local/bin/psql \
            --host {source_host} \
            --port {source_port} \
            --username {source_user} \
            -At --command '{database_select_query}' \
        postgres
    """
    
  • 给subprocess补充PATH环境变量
    手动把PostgreSQL的bin目录添加到subprocess的环境变量中,保证系统能找到psql:

    import os
    # 获取系统原有PATH
    current_path = os.environ.get("PATH", "")
    # 替换成你实际的PostgreSQL bin目录
    pg_bin_path = "/usr/local/bin"
    new_path = f"{pg_bin_path}:{current_path}"
    
    output = subprocess.run(
        shlex.split(database_select_command),
        capture_output=True,
        shell=False,
        env={"PGPASSWORD": source_password, "PATH": new_path},
    )
    
  • 直接构造参数列表(推荐)
    放弃用字符串拼接命令再拆分的方式,直接构造参数列表传递给subprocess,既能避免引号转义问题,也能绕开shlex解析的潜在问题:

    cmd_args = [
        "psql",  # 同样可以替换成绝对路径
        "--host", source_host,
        "--port", source_port,
        "--username", source_user,
        "-At",
        "--command", database_select_query,
        "postgres"
    ]
    output = subprocess.run(
        cmd_args,
        capture_output=True,
        shell=False,
        env={"PGPASSWORD": source_password, "PATH": new_path},
    )
    

内容的提问来源于stack exchange,提问作者Tim Estes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:16:03