【问题标题】:Python, os.system and subprocess.call both don't work for variable string commandPython、os.system 和 subprocess.call 都不适用于可变字符串命令
【发布时间】:2018-12-08 00:43:03
【问题描述】:

我正在尝试使用 python 向另一个应用程序发出命令,但它似乎只承认命令的一部分。以下是有问题的代码行:

command = 'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)
print (command)
os.system(command)

我对 Python 还很陌生,所以如果这是为包含许多变量的目录名称构造字符串的奇怪方式,请原谅我。但是,打印功能总是返回我想要的确切命令,如果我只是手动将其复制并粘贴到命令提示符中,它将按预期运行。

potreeconverter C:\Users\thomas\source\test.las -q NICE -p test –o C:\Users\thomas\source\55555\55555\test

该命令被应用程序接受,但它忽略 -o 参数,该参数指定应用程序的输出目录。如果我使用 subprocess.call,它会做同样的事情。该命令的任何其他部分都不会被忽略。

我读到这个问题可以通过让 python 将命令写入批处理文件,然后发送批处理文件来解决。我真的不想这样做,因为它效率很低。还有其他人知道的方法可以避免这种情况吗?

另外,我不确定这意味着什么,但我认为这很奇怪,也许很重要。当出现这个问题,并且只有出现这个问题时,程序选择的默认输出目录而不是我指定的那个,才会使用正斜杠而不是反斜杠。

【问题讨论】:

  • os.system()的返回值是多少?
  • 我将命令设置为变量并打印它,它返回 0
  • 如果它返回零,那么它似乎有工作。你需要看看potreeconverter,比如你有多个版本吗? potreeconverter 是否接受带有 \ 目录分隔符的文件路径?顺便说一句,/ 在 Windows 上工作,这可能值得一试。
  • 是的,正斜杠在大多数情况下都可以在 Windows 上使用,但我相信在一些较旧的程序中除外。我会尝试这样做,并确保周围没有可能不同版本的 potreeconverter,python 可能首先看到的版本是不正确的。

标签: python subprocess os.system


【解决方案1】:

你需要转义你的反斜杠。
反斜杠是一个特殊字符,这就是为什么您可以编码特殊字符,例如制表符 (\t)、换行符 (\n) 等等。
所以你可以替换这个:

command = 'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)  

与:

command = 'potreeconverter {} -q NICE -p {} –o {}\\{}\\{}\\{}'.format(path,folder,pathup[0],cid,wpid,folder) 

您也可以使用 python 的 raw string notation,我个人认为它更好,并且更易于维护:

command = r'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)

这样做只是告诉 python 不要将 any 字符视为特殊字符(格式字符串除外,但这种情况不算在内)。
现在,关于你所说的它是一种奇怪的路径制作方式,有一个更好的方法,那就是os.path.join。这需要任何参数,并将它们作为路径加入。例如它会这样做:

>>> os.path.join('C:\\tuna', 'fish', 'directory')
'C:\\tuna\\fish\\directory'
>>>

这里有3个主要优点:它将根据系统在/\之间进行选择(Windows\DOS上的\,Unix/Linux上的/等...),它可以接受任意数量的参数,并且更具可读性。在你的情况下,你可以这样做:

import os.path

base = 'potreeconverter {} -q NICE -p {} –o'
path = os.path.join(pathup[0], cid, wpid, folder)
command = ' '.join((base, path))

您的代码也可以工作,但这是使用路径的推荐方式。
如果您有任何疑问,请询问。祝你有美好的一天!

【讨论】:

  • 非常感谢您提供的超级全面的答案!但实际上所有这些方法都给出了我已经得到的相同结果。你知道为什么会这样吗?
  • 不,我不知道,这很奇怪。如果可以的话,您能否发布整个代码或一个最小的、可运行的示例,以便我尝试一下?
  • 我可以看看你在调用print(command) 时得到了什么,也许也可以尝试将它写入一个文件,看看它是如何编码的?
  • 在我花时间做这件事之前,经过一番思考,我想我可能知道是什么原因造成的。我在 Windows 上。您是否认为我使用 python 而不是 Windows 命令外壳这一事实可能会使应用程序误以为它没有在 Windows 计算机上运行,​​而这可能会导致这个问题?它默认的输出目录是用Unix/Linux格式写的,但只有当我通过python发出命令时。
  • 这似乎不太可能,但如果你使用的是 cygwin 之类的东西,也许有可能,但我不知道
【解决方案2】:

为了确保我不会让每个人都悬而未决,我想出了解决方案。这很奇怪。我所做的只是以不同的顺序调用参数,现在它每次都有效。如果我手动输入命令,它们会以任何顺序工作,但是如果我从 python 发出命令,它似乎只有在我首先编写输出参数时才会起作用。不确定这是 python 的问题还是我正在编写命令的应用程序的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 2022-10-05
    • 2019-11-17
    • 2019-03-23
    • 2015-07-02
    • 2018-09-14
    • 1970-01-01
    • 2017-01-06
    相关资源
    最近更新 更多