Windows 上的 Python:作为子进程参数的路径被修改并生成错误

发布于 2024-10-22 09:14:35 字数 816 浏览 1 评论 0原文

我在 Windows 和 Python 2.6 上使用子进程,如下所示。我正在尝试使用旧解析器应用程序(假设 parser.py)解析文本文件,如下所示:

import subprocess
k = subprocess.Popen(['python', 'parser.py', '-f C:\Report1\2011-03-14.txt'],
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print k.communicate()

这里的问题在于文件名传递到旧应用程序的方式,我无法更改代码,但只能使用 Python 访问它。

它生成以下错误:

IOError: [Errno 22] invalid mode (\'r\') or filename: C:\\Report1\\2011-03-14.txt

当我从回溯复制修改的文件名(带有双正斜杠)以检查是否存在时,系统无法找到它。

问题:如何将路径作为参数传递,以便在不更改为双斜杠的情况下对其进行处理,以便系统可以读取文件?

注意:os.sep 也不能解决该问题。

编辑:使用 os.system 执行效果很好,但问题是获取输出以供以后使用。目前我在一个模块(run_parser.py)中使用 os.sytem,然后在另一个模块(get_parse_status.py)中使用子进程,该子进程打开 run_parser.py 来获取输出。会欣赏任何比这更好的东西。

谢谢你的时间。

Am using subprocess on Windows and Python 2.6 as follows. I am trying to parse a text file using a legacy parser application (assume parser.py) as follows:

import subprocess
k = subprocess.Popen(['python', 'parser.py', '-f C:\Report1\2011-03-14.txt'],
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print k.communicate()

The issue here is with the way filename gets passed to the legacy application where I cannot change the code but only can access it using Python.

It generates with the following error:

IOError: [Errno 22] invalid mode (\'r\') or filename: C:\\Report1\\2011-03-14.txt

When I copy the modified filename(with double forward slashes) from the traceback to check the existence, the system is not able to find it.

Question: How can I pass the path as argument so that it gets treated without getting changed to double slashes so that the system can read the file?

NOTE: os.sep also does not resolve the issue.

EDIT: Executing using os.system works perfectly, but the issue there is to grab the output for later use. Am currently using os.sytem in a module(run_parser.py) and then using subprocess in another module(get_parse_status.py) that Popens run_parser.py to grab the output. Would appreciate anything that is better than this.

Thanks for the time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月打碎记忆 2024-10-29 09:14:36

更改参数列表以将路径编码为原始字符串:

k = subprocess.Popen(['python', 'parser.py', '-f', r'C:\Report1\2011-03-14.txt'],
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

一个读取文件并报告长度的简单程序:

import sys
import os
userinput = sys.argv[1]
data = open(userinput, 'rb').read()
datalength = len(data)
fname = os.path.basename(userinput)
print "%s datasize = %s" % (fname, datalength)

然后通过解释器调用它:

>>> k = subprocess.Popen(['python', 'test2.py', 'w:\bin\test2.py'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> k.communicate()
5: ('Traceback (most recent call last):\r\n  File "w:\\bin\\test2.py", line 4, in <module>
data = open(userinput, \'rb\').read()
IOError: [Errno 22] invalid mode (\'rb\') or filename: 'w:\\x08in\\test2.py', None)
>>> k = subprocess.Popen(['python', r'w:\bin\test2.py', r'w:\bin\test2.py'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> k.communicate()
6: ('test2.py datasize = 194\n', None)

Change your parameter list to encode the path as a raw string:

k = subprocess.Popen(['python', 'parser.py', '-f', r'C:\Report1\2011-03-14.txt'],
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

a simple program that reads a file and reports the length:

import sys
import os
userinput = sys.argv[1]
data = open(userinput, 'rb').read()
datalength = len(data)
fname = os.path.basename(userinput)
print "%s datasize = %s" % (fname, datalength)

Then to call it through the interpreter:

>>> k = subprocess.Popen(['python', 'test2.py', 'w:\bin\test2.py'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> k.communicate()
5: ('Traceback (most recent call last):\r\n  File "w:\\bin\\test2.py", line 4, in <module>
data = open(userinput, \'rb\').read()
IOError: [Errno 22] invalid mode (\'rb\') or filename: 'w:\\x08in\\test2.py', None)
>>> k = subprocess.Popen(['python', r'w:\bin\test2.py', r'w:\bin\test2.py'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> k.communicate()
6: ('test2.py datasize = 194\n', None)
娇柔作态 2024-10-29 09:14:36

“C:\Report1\2011-03-14.txt” 与路径 C:\Report1\2011-03-14.txt 不同。它实际上是一些字节串,'C:\\Report1\x811-03-14.txt'。奇怪的是,这听起来不像是你的问题,但它可能是相关的。 r"C:\Report1\2011-03-14.txt" 解决了这个问题。

但请注意,打印表示中的双反斜杠并不一定意味着实际上有两个反斜杠。 '\\' 是长度为 1 的 Python 字符串。

"C:\Report1\2011-03-14.txt" isn't the same as the path C:\Report1\2011-03-14.txt. It's actually some bytestring, 'C:\\Report1\x811-03-14.txt'. Strangely enough it doesn't sound like this is your issue, but it might be related. r"C:\Report1\2011-03-14.txt" fixes this.

But be aware that double backslashes in the printed representation doesn't necessarily mean that there are actually two backslashes. '\\' is a Python string of length 1.

抱猫软卧 2024-10-29 09:14:36

“C:\Report1\2011-03-14.txt”与路径 C:\Report1\2011-03-14.txt 不同。它实际上是一些字节串,'C:\Report1\x811-03-14.txt'。奇怪的是,这听起来不像是你的问题,但它可能是相关的。 r"C:\Report1\2011-03-14.txt" 修复了此问题。

但请注意,打印表示中的双反斜杠并不一定意味着实际上有两个反斜杠。 '\' 是长度为 1 的 Python 字符串。

您尝试过吗:

from subprocess import Popen, PIPE
k = Popen(r'python parser.py -f "C:\Report1\2011-03-14.txt"',
          shell=True, 
          stdout=PIPE, 
          stderr=STDOUT)
print k.communicate()

我发现,通常当通过 Popen 在命令行上传递 args 时,将参数括在双引号中是让它正常工作的唯一可靠方法。我也不总是信任调用 Popen 的列表方法,并且通常自己形成命令。另请注意原始指标 (r'')。

"C:\Report1\2011-03-14.txt" isn't the same as the path C:\Report1\2011-03-14.txt. It's actually some bytestring, 'C:\Report1\x811-03-14.txt'. Strangely enough it doesn't sound like this is your issue, but it might be related. r"C:\Report1\2011-03-14.txt" fixes this.

But be aware that double backslashes in the printed representation doesn't necessarily mean that there are actually two backslashes. '\' is a Python string of length 1.

Have you tried:

from subprocess import Popen, PIPE
k = Popen(r'python parser.py -f "C:\Report1\2011-03-14.txt"',
          shell=True, 
          stdout=PIPE, 
          stderr=STDOUT)
print k.communicate()

I find that often when passing args on the command line via Popen, enclosing the parameters in double-quotes is the only reliable way to get it to behave. I also don't always trust the list method of calling Popen and usually form the command myself. Notice also the raw indicator (r'').

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文