在shell中执行此操作会获得切实的结果:
wget -O c1 --no-cache "http://some.website" | sed "1,259d" c1 | sed "4,2002d"
在Python中执行此操作无需任何操作:
subprocess.call(shlex.split("wget -O c1 --no-cache \"http://some.website/tofile\""))
c1 = open("c1",'w')
first = subprocess.Popen(shlex.split("sed \"1,259d\" c1"), stdout=subprocess.PIPE)
subprocess.Popen(shlex.split("sed \"4,2002d\""), stdin=first.stdout, stdout=c1)
c1.close()
这样做也没有结果:
c1.write(subprocess.Popen(shlex.split("sed \"4,2002d\""), stdin=first.stdout, stdout=subprocess.PIPE).communicate()[0])
通过'得到我什么都不'我的意思是文件中的空白输出。有没有人在这里看到任何与众不同的东西?
答案 0 :(得分:3)
我总是使用plumbum来运行外部命令。它提供了一个非常直观的界面,当然,也为我提供了逃避。
看起来像:
from plumbum.cmd import wget, sed
cmd1 = wget['-O', 'c1']['--no-cache']["http://some.website"]
cmd2 = sed["1,259d"]['c1'] | sed["4,2002d"]
print cmd1
cmd1() # run it
print cmd2
cmd2() # run it
答案 1 :(得分:2)
语句c1 = open("c1",'w')
打开文件c1
进行写入并截断任何现有数据,因此写入文件的所有内容都会在调用sed之前被删除。
无论如何,我认为shlex.split
通常很尴尬。我更喜欢手动构建args列表:
from subprocess import Popen, PIPE
p0 = Popen(['wget', '-O', '-', 'http://www.google.com'], stdout=PIPE)
p1 = Popen(['sed', '2,8d'], stdin=p0.stdout, stdout=PIPE)
with open('c1', 'w') as c1:
p2 = Popen(['sed', '2,7d'], stdin=p1.stdout, stdout=c1)
p2.wait()
然而,没有明显的理由让Python程序员应该调用sed。 Python有字符串方法和正则表达式。另外,您可以使用urllib2.urlopen
代替wget。
答案 2 :(得分:1)
为什么不直接在管道中执行所有操作并将输出发送到文件?
wget -O - "http://www.google.com" | sed "1,259d" | sed "4,2002d" > c1
或者,如果您不想将其发送到文件,而是希望它在stdout上:
wget -O - "http://www.google.com" | sed "1,259d" | sed "4,2002d"
如果你想用Python做到这一点:
pipe = subprocess.Popen(shlex.split("wget -O - \"http://www.google.com\" | sed \"1,259d\" | sed \"4,2002d\""), stdout=subprocess.PIPE)
result = pipe.communicate()[0]
答案 3 :(得分:0)
为了让那些或多或少可能遇到同一类型问题的人们的生活更轻松,我决定发布最终修订后的代码,该代码考虑了c1
和覆盖的评论数据的。特别感兴趣的是communicate()
的使用,这有助于完全消除僵尸过程的任何表现,这非常令人恼火。此外,我发现在不需要管道的部分使用subprocess.call
很有用。最后不需要wait()
。最终,远离sed
和wget
是一个好主意,特别是使用Python的内置工具和urllib2
。
p0 = subprocess.call(shlex.split("wget -Oc1 --no-cache \"http://Some.website/tofile\""))
p1 = subprocess.Popen(shlex.split("sed \"1,261d\" c1"), stdout=subprocess.PIPE)
with open("cc1", 'w') as cc1:
p2 = subprocess.Popen(shlex.split("sed \"3,2002d\""), stdin=p1.stdout, stdout=cc1)
p2.communicate()
p1.communicate()
p3 = subprocess.call(shlex.split("mv cc1 c1"))