Python“找不到指定的文件”,但 os.path.exists() 为 True

问题描述 投票:0回答:1

我在 Windows 11 虚拟机中运行 Python 3.7.16。假设我想通过 subprocess.Popen 使用 CMD

C:\Users\Foo\Documents\bar\doc.txt
调用来获取文件(存储在
dir
)的信息(有更好的方法来完成此任务,但它演示了问题)。

对 os.path.exists() 的调用表示该文件存在(这是正确的!),但是当我尝试使用 subprocess.Popen 检查它时,Windows 说它找不到它。

import subprocess
import os
path = os.path.join("C:", os.sep, "Users", "Foo", "Documents", "bar", "doc.txt")
# path = 'C:\\Users\\Foo\\Documents\\bar\\doc.txt'
os.path.exists(path) # -> True
subprocess.Popen([fr"dir {path}"]) # -> "The system cannot find the file specified"
subprocess.Popen([fr"dir {path}"], shell = True) # -> "The filename, directory name, or volume label syntax is incorrect."

知道这里可能出了什么问题吗?

python windows subprocess popen
1个回答
0
投票

您遇到的问题与 subprocess.Popen 函数如何处理参数和 shell 参数有关。使用 shell 参数时,命令应作为单个字符串传递,而不是作为单独参数的列表传递。

以下是修改代码以使其正常工作的方法:

import subprocess
import os

path = os.path.join("C:", os.sep, "Users", "Foo", "Documents", "bar", "doc.txt")

# Using shell=True and passing the command as a single string
subprocess.Popen(fr'dir "{path}"', shell=True)

在此示例中,我们使用 shell=True 并将命令作为单个字符串传递。此外,我们在路径周围添加了双引号来处理文件路径中的任何空格。

请记住,使用 shell=True 可能会产生安全隐患,因为它可能会使您的代码暴露于潜在的 shell 注入漏洞。只要有可能,建议避免使用 shell=True 并使用 Popen 调用的列表形式,传递各个参数。

如果您更喜欢使用列表形式并避免 shell=True,您可以使用以下方法:

import subprocess
import os

path = os.path.join("C:", os.sep, "Users", "Foo", "Documents", "bar", "doc.txt")

# Using the list form and avoiding shell=True
subprocess.Popen(["cmd", "/c", "dir", path])

在此版本中,我们显式调用带有“/c”标志的“cmd”命令来执行dir命令。这种方法避免了对 shell=True 的需要,并使您的代码更安全。

© www.soinside.com 2019 - 2024. All rights reserved.