【问题标题】:Python: How to save the output of os.system [duplicate]Python:如何保存 os.system 的输出 [重复]
【发布时间】:2011-10-31 01:00:54
【问题描述】:

在 Python 中,如果我使用“wget”通过 os.system("wget) 下载文件,它会在屏幕上显示如下:

 Resolving...

 Connecting to ...

 HTTP request sent, awaiting response...

 100%[====================================================================================================================================================================>] 19,535,176  8.10M/s   in 2.3s 

等在屏幕上。

如何将此输出保存在某个文件中而不是在屏幕上显示?

目前我运行的命令如下:

theurl = "< file location >"
downloadCmd = "wget "+theurl
os.system(downloadCmd)

【问题讨论】:

  • 你为什么首先调用 wget 而不是使用 python 标准库中的东西?
  • 你能举个例子解释一下吗...

标签: python


【解决方案1】:

wget 进程只是写入 STDOUT(如果发生不好的事情可能还会写入 STDERR),这些仍然“连接”到终端。

要让它停止这样做,重定向(或关闭)所述文件句柄。查看subprocess 模块,它允许在启动进程时配置所述文件句柄。 (os.system 只留下衍生进程的 STDOUT/STDERR,因此它们是继承的,但子进程模块更灵活。)

请参阅 Working with Python subprocess - Shells, Processes, Streams, Pipes, Redirects and More 以获取许多很好的示例和解释(它介绍了 STDIN/STDOUT/STDERR 的概念并从那里开始工作)。

可能有比使用 wget 更好的方法来处理这个问题——但我会把它留给其他答案。

编码愉快。

【讨论】:

  • 我导入了模块子流程。然后我按如下方式使用它 ----->process = subprocess.Popen(downloadCmd, shell=False, stdout=subprocess.PIPE) 但它给了我错误:File "/usr/lib64/python2.4/ subprocess.py”,第 550 行,在 init errread,errwrite)文件“/usr/lib64/python2.4/subprocess.py”,第 996 行,在 _execute_child 中引发 child_exception OSError:[Errno 2]没有这样的文件或目录
【解决方案2】:

os.system 函数通过 shell 运行命令,因此您也可以将任何 stdio 重定向放在那里。您还应该使用-q 标志(安静)来wget。

cmd = "wget -q " + theurl + " >/dev/null 2>&1" 

但是,在 python 中有更好的方法来执行此操作,例如 libcurl 的 pycurl 包装器或“stock”urllib2 模块。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,您可以使用 Python 原生库模块来执行 I/O,或者您可以修改命令行以重定向输出。

    但是为了完全控制输出,最好的办法是使用 Python subprocess 模块而不是 os.system()。使用subprocess 可以让您捕获输出并检查它,或者将任意数据输入标准输入。

    如果您想要一种快速而简单的方式来运行某些东西,请使用os.system()。如果您想完全控制自己的运行方式,请使用subprocess

    【讨论】:

      【解决方案4】:

      要回答您的直接问题,正如其他人所提到的,您应该强烈考虑使用subprocess 模块。这是一个例子:

      from subprocess import Popen, PIPE, STDOUT
      
      wget = Popen(['/usr/bin/wget', theurl], stdout=PIPE, stderr=STDOUT)
      stdout, nothing = wget.communicate()    
      
      with open('wget.log', 'w') as wgetlog:
          wgetlog.write(stdout)
      

      但是,无需调用系统来下载文件,让 python 为您完成繁重的工作。

      使用urllib

      try: 
          # python 2.x
          from urllib import urlretrieve
      except ImportError:
          # python 3.x
          from urllib.request import urlretrieve
      
      urlretrieve(theurl, local_filename)
      

      urllib2

      import urllib2
      
      response = urllib2.urlopen(theurl)
      with open(local_filename, 'w') as dl:
          dl.write(response.read())
      

      local_filename 是您选择的目标路径。 有时可以自动确定此值,但具体方法取决于您的具体情况。

      【讨论】:

      • 我收到以下错误:文件“python.py”,第 129 行,open('wget.log', 'w') as wgetlog: ^ SyntaxError: invalid syntax
      • 不使用关键字“with”和“as”,它可以成功运行.... wget = Popen(['/usr/bin/wget', theurl], stdout=PIPE, stderr= STDOUT) 标准输出,什么都没有 = wget.communicate() wgetlog = open('wget.log', 'w') wgetlog.write(stdout)
      • @nsh 是的,抱歉。 with statement 在 python 2.6 及更高版本中默认启用,您可以在 python 2.5 中通过添加 from __future__ import with_statement 作为第一个导入来启用它。如果您使用的是 python 2.4 或更早版本,请参阅stackoverflow.com/questions/3770348/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 2013-10-16
      • 1970-01-01
      • 2015-12-28
      • 2022-10-14
      • 2014-02-16
      相关资源
      最近更新 更多