Python中使用subprocess.Popen调用和手动在cmd运行效果不一样

我在使用python做一个公益frp时,程序在创建好配置文件,然后在使用 subprocess.Popen调用系统命令运行frp时,frp死活接收不到-c命令传入的配置文件路径,提示:

2023/07/07 15:03:11 [W] [service.go:101] login to server failed: dial tcp 0.0.0.0:7000: connectex: No connection could be made because the target machine actively refused it.
dial tcp 0.0.0.0:7000: connectex: No connection could be made because the target machine actively refused it.

但我在cmd中运行程序生成的手动启动命令时,就可以正常运行,求指点,下面是在调用时使用的代码:

    temp_path = os.path.join(os.environ['TEMP'], '')
    print(temp_path)
#省略配置文件生成逻辑
        current_path = os.path.abspath(__file__)
        current_dir = os.path.dirname(current_path)
        cmd = current_dir+"\\frp\\frpc.exe --config "+temp_path+"AZFRP\\frpc.ini"
        print("FRP已启动,按 Ctrl + c 键停止")
        proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,encoding="utf-8")
        while True:
            output = proc.stdout.readline()
            if output == '' and proc.poll() is not None:
                break
            if output:
                print(output.strip())

        # 检查命令执行状态
        if proc.returncode != 0:
            print("Error: Command '{}' failed with return code {}".format(cmd, proc.returncode))

模块、配置文件是完全没问题的
如果对我有帮助,我会在评论进行打赏

根据你提供的信息,出现问题的是在使用subprocess.Popen调用系统命令运行frp时,frp无法接收到传入的配置文件路径。

从你的代码中可以看到,你使用了shell=True参数来执行命令,这将导致命令被解释为一个字符串并由shell解析。在Windows系统上,shell=True将使用默认的Windows命令提示符解析命令。这可能导致一些问题。

为了解决这个问题,你可以尝试不使用shell=True,而是将命令拆分成一个字符串列表传递给subprocess.Popen。这样可以避免shell解析命令时的一些潜在问题。修改后的代码如下:

import subprocess

temp_path = os.path.join(os.environ['TEMP'], '')
print(temp_path)

# 省略配置文件生成逻辑

current_path = os.path.abspath(__file__)
current_dir = os.path.dirname(current_path)

# 使用字符串列表传递命令,避免使用shell=True
cmd = [
    current_dir + "\\frp\\frpc.exe",
    "--config",
    temp_path + "AZFRP\\frpc.ini"
]

print("FRP已启动,按 Ctrl + c 键停止")
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, encoding="utf-8")
while True:
    output = proc.stdout.readline()
    if output == '' and proc.poll() is not None:
        break
    if output:
        print(output.strip())

# 检查命令执行状态
if proc.returncode != 0:
    print("Error: Command '{}' failed with return code {}".format(cmd, proc.returncode))

通过这种方式,subprocess.Popen将不会使用shell来解析命令,而是直接执行命令。

如若有用,还望博友采纳!

temp_path要使用绝对路径,不要用相对路径