【问题标题】:How to execute command line in a python loop?如何在 python 循环中执行命令行?
【发布时间】:2014-06-06 01:11:18
【问题描述】:

我正在尝试确定使用 python 在命令行中执行某些操作的最佳方式。我已经在单个文件上使用subprocess.Popen() 完成了这项工作。但是,我正在尝试确定使用许多不同文件多次执行此操作的最佳方法。我不确定我是否应该创建一个批处理文件然后在命令中执行它,或者我是否只是在我的代码中遗漏了一些东西。新手编码员在这里,所以我提前道歉。下面的脚本在我使用循环时返回返回码 1,但在不在循环中时返回 0。手头任务的最佳方法是什么?

def check_output(command, console):
    if console == True:
        process = subprocess.Popen(command)
    else:
        process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
    output, error = process.communicate()
    returncode = process.poll()
    return returncode, output, error

for file in fileList.split(";"):
    ...code to create command string...
    returncode, output, error = check_output(command, False)
    if returncode != 0:
        print("Process failed")
        sys.exit()

编辑:示例命令字符串如下所示:

C:\Path\to\executable.exe -i C:\path\to\input.ext -o C:\path\to\output.ext

【问题讨论】:

  • 你想完成什么?运行一堆命令并将它们的输出输入 Python?将每个命令链接在一起?并行运行它们?
  • 按顺序运行它们,文件 1,文件 2,...我有一个可执行文件,我想在多个文件上运行,一次一个。
  • 我们能否获得一个示例,说明当命令字符串被传递到check_output 时的样子?除了 Popen (stder) 中的一个错字之外,我看不出它有任何失败的原因。
  • 使用子进程的内置 check_output 方法进行错误检查
  • @wils484,process.communicate() 错误返回 None。

标签: python windows loops python-2.7 popen


【解决方案1】:

尝试使用 commands 模块(仅在 python 3 之前可用)

>>> import commands
>>> commands.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')

您的代码可能如下所示

import commands

def runCommand( command ):
    ret,output = commands.getstatutoutput( command )
    if ret != 0:
        sys.stderr.writelines( "Error: "+output )
    return ret

for file in fileList.split(';'):
    commandStr = ""
    # Create command string
    if runCommand( commandStr ):
        print("Command '%s' failed" % commandStr)
        sys.exit(1)

您对要解决的问题并不完全清楚。如果我不得不猜测为什么您的命令在循环中失败,那可能是您处理 console=False 情况的方式。

【讨论】:

    【解决方案2】:

    如果您只是一个接一个地运行命令,那么最简单的方法可能是抛弃 Python 并将您的命令粘贴到 bash 脚本中。我假设您只想检查错误并在其中一个命令失败时中止。

    #!/bin/bash
    
    function abortOnError(){
        "$@"
        if [ $? -ne 0 ]; then
            echo "The command $1 failed with error code $?"
            exit 1
        fi
    }
    
    abortOnError ls /randomstringthatdoesnotexist
    echo "Hello World" # This will never print, because we aborted
    

    更新:OP 用表明他在 Windows 上的示例数据更新了他的问题。 您可以通过cygwin 或其他各种软件包获得适用于Windows 的bash,但如果您在Windows 上使用PowerShell 可能更有意义。不幸的是,我没有 Windows 盒子,但应该有类似的错误检查机制。这是用于 PowerShell 错误处理的 reference。

    【讨论】:

      【解决方案3】:

      您可以考虑使用subprocess.call

      from subprocess import call
      
      for file_name in file_list:
          call_args = 'command ' + file_name
          call_args = call_args.split() # because call takes a list of strings 
          call(call_args)
      

      它也会输出 0 表示成功,1 表示失败。

      【讨论】:

      • 这会产生与我的代码中的subprocess.Popen() 相同的结果。奇怪的是,可执行文件似乎做了它应该做的事情,但仍然返回1。我是否可能需要等待子流程?
      • @Barbarossa 如果子进程正确完成,进程如何退出?
      • 对不起,我应该提到的。我注释掉了if returncode != 0 部分,看看它是否会在不验证子进程是否完成的情况下运行。如果我不担心返回码,一切似乎都可以正常工作,但我假设返回码 1 表示有错误。
      • @Barbarossa 我会尝试打印返回码,看看它实际发生了什么。在命令完成之前,我无法想象它具有已定义的状态。
      【解决方案4】:

      您的代码试图完成的是对文件运行命令,并在出现错误时退出脚本。 subprocess.check_output 实现了这一点 - 如果子进程以错误代码退出,则会引发 Python 错误。根据您是否要显式处理错误,您的代码将如下所示:

      file in fileList.split(";"):
          ...code to create command string...
          subprocess.check_output(command, shell=True)
      

      如果有,它将执行命令并打印shell错误消息,或者

      file in fileList.split(";"):
          ...code to create command string...
          try:
              subprocess.check_output(command,shell=True)
          except subprocess.CalledProcessError:
              ...handle errors...
              sys.exit(1)
      

      这将打印 shell 错误代码并退出,就像在您的脚本中一样。

      【讨论】:

        猜你喜欢
        • 2012-06-26
        • 2015-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-21
        相关资源
        最近更新 更多