【问题标题】:Python on Windows: path as subprocess argument gets modified and generating errorWindows 上的 Python:作为子进程参数的路径被修改并生成错误
【发布时间】:2011-03-14 18:48:51
【问题描述】:

我在 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 来获取输出。会感激任何比这更好的东西。

感谢您的时间。

【问题讨论】:

  • 您可以访问 parser.py 吗?您可以发布任何相关部分吗?
  • parser.py 是一个大应用程序。它失败的相关内容是当它尝试将文件输入作为参数 -f 读取时。
  • k = subprocess.Popen(['python', 'parser.py', '-f','"C:\Report1\2011-03-14.txt"'], shell=是的,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)试试这个。
  • 感谢 Nate 和 Uku。不幸的是,不起作用。得到同样的错误。
  • 您确定是逐字粘贴的吗?它是 ' 然后是 ".

标签: python subprocess


【解决方案1】:

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

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)

【讨论】:

    【解决方案2】:

    "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 字符串。

    【讨论】:

    • @martineau 感谢您的编辑。我应该学会在睡眠不足时不要回答问题。 :)
    【解决方案3】:

    “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 的 list 方法,并且通常自己形成命令。还要注意原始指示符 (r'')。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      • 2019-08-24
      • 2022-07-05
      • 2017-06-15
      • 2019-01-30
      • 1970-01-01
      • 2011-05-30
      相关资源
      最近更新 更多