【问题标题】:Python subprocess.Popen() not running commandPython subprocess.Popen()未运行命令
【发布时间】:2019-08-02 04:53:28
【问题描述】:

我正在尝试使用 subprocess.Popen() 在我的脚本中运行命令。代码是:

output = Popen(["hrun DAR_MeasLogDump " + log_file_name], stdout=subprocess.PIPE, stderr = subprocess.PIPE, executable="/bin/csh", cwd=cwdir, encoding='utf-8')

当我打印输出时,它会打印出创建的 shell 输出,而不是列表中的实际命令。我尝试摆脱 executable='/bin/csh',但 Popen 甚至无法运行。

我也尝试过使用subprocess.communicate(),但也没有用。我还将获得 shell 输出,而不是实际的命令运行。

由于安全问题,我想完全避免使用shell=True

编辑:在许多不同的尝试中,“hrun”没有被识别。 “hrun”是正在调用的 Pearl 脚本,DAR_MeasLogDump 是操作,log_file_name 是脚本将调用其操作的文件。是否需要进行任何类型的设置或配置才能识别“hrun”?

【问题讨论】:

  • 您是否尝试过按原样将其设为列表:["hrun DAR_MeasLogDump", log_file_name]
  • 是的,我试过了,但是没有任何东西写入“输出”。当我在命令行上运行命令时,我希望将输出存储在“输出”中。

标签: python subprocess popen


【解决方案1】:

我认为问题在于 Popen 需要命令的每个部分(命令 + 选项)的列表,Popen 内部子进程的documentation 有一个示例。因此,要使脚本中的该行起作用,您需要这样编写:

output = Popen(["/bin/csh", "hrun", "DAR_MeasLogDump", log_file_name], stdout=subprocess.PIPE, stderr = subprocess.PIPE)

我已经删除了可执行参数,但我想它也可以这样工作。

【讨论】:

    【解决方案2】:

    这适用于 cat 示例:

    import subprocess
    
    log_file_name='-123.txt'
    
    output = subprocess.Popen(['cat', 'DAR_MeasLogDump' + log_file_name], 
                                    stdout=subprocess.PIPE, 
                                    stderr=subprocess.STDOUT)
    stdout, stderr = output.communicate()
    print (stdout)
    print (stderr)
    

    我认为您只需更改您的“hrun”命令

    【讨论】:

      【解决方案3】:

      您正在创建subprocess.Popen 的实例,但没有执行它。

      你应该试试:

      p = Popen(["hrun", "DAR_MeasLogDump ", log_file_name], stdout=subprocess.PIPE, stderr = subprocess.PIPE, cwd=cwdir, encoding='utf-8')
      
      out, err = p.communicate()  # This will get you output
      

      如果不使用shell=True,则应将Args 作为序列传递,然后使用executable should not be required

      请注意,如果您没有使用Popen 的高级功能,文档建议使用subprocess.run

      from subprocess import run
      
      p = run(["hrun", "DAR_MeasLogDump ", log_file_name], capture_output=True, cwd=cwdir, encoding='utf-8')
      
      out, err = p.communicate()  # This will get you output
      

      【讨论】:

      • 感谢您的回复!当我尝试运行()时没有找到“hrun”。 “hrun”是一个 Pearl 脚本,它从另一个执行 DAR_MeasLogDump 操作的目录调用。为了让 run/Popen 识别 hrun,是否需要进行任何类型的设置或配置?
      • 那么你应该从它的绝对路径调用它,或者让它对PATH可用。并确保它是可执行的,并带有适当的 shebang。
      【解决方案4】:

      在这里指定一个奇怪的 shell 和一个显式的 cwd 似乎完全不合适(假设 cwdir 定义到当前目录)。

      如果subprocess 的第一个参数是一个列表,则没有 shell 参与。

      result = subprocess.run(["hrun", "DAR_MeasLogDump", log_file_name],
          stdout=subprocess.PIPE, stderr = subprocess.PIPE,
          universal_newlines=True, check=True)
      output = result.stdout
      

      如果您需要在旧版 Python 下运行它,可以使用 check_output 而不是 run

      您通常希望避免使用Popen,除非您需要执行更高级别的包装函数无法执行的操作。

      【讨论】:

      【解决方案5】:

      试试:

      output = Popen(["-c", "hrun DAR_MeasLogDump " +log_file_name], stdout=subprocess.PIPE, stderr = subprocess.PIPE, executable="/bin/csh", cwd=cwdir, encoding='utf-8')
      

      csh 期待 -c "full command here"。如果没有-c,我认为它只是试图将其作为文件打开。

      【讨论】:

      • 感谢您的回复!我试过这样做,没有任何东西被写入“输出”。当我在命令行上运行相同的命令时,我会看到一个输出,这是我希望存储到“输出”的内容。
      • 我第一次弄错了,因为我没有注意到executable="/bin/csh"。查看更新的答案。
      • 我用“-c”试过了,但仍然没有任何东西存储到“输出”。命令没有运行,还是传递给 Popen 的参数有问题?
      • Popen() 不返回输出。添加"-c"后,您仍然需要拨打output.communicate()。您也可以尝试check_output(),以获得更简单的路线。
      • 使用 output.communicate() 时,无法识别“DAR_MeasLogDump”(没有这样的文件或目录)。本来就是一个动作。令人惊讶的是,“hrun”并没有引发错误,该线程上的大多数其他 cmets 都是这种情况。
      猜你喜欢
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 2012-02-28
      • 2023-03-08
      • 1970-01-01
      • 2021-08-24
      相关资源
      最近更新 更多