我正在尝试使用python做一些文件系统的东西,因为我不想处理复杂的shell脚本,而是宁愿将我的所有编程限制在python中。 shell命令在' search_string'读取目录中的文件名,并将前10个名称写入文件。
search_string = "find " + rootDir + "/"+str(k) +" -iname \"*\" -type f | head -10 >> negatives" + str(i) + ".txt"
print(search_string)
subprocess.call(search_string, shell=True)
此代码适用于我的ubuntu 14.04 pc,但不适用于最终必须运行的aws,给出错误:
find: `standard output': Broken pipe
find: write error
ubuntu@ip:$ uname -r
3.13.0-37-generic
所以我决定将long shell命令写入一个我认为很容易调用的文件(在使用chmod命令使shell脚本文件可执行后):
search_string = "sudo find " + rootDir + "/"+str(k) +" -iname \"*\" -type f | head -10 >> trainingfiles/negatives" + str(i) + ".txt"
f=open("cmd.sh","w")
f.write(search_string)
f.flush()
os.fsync(f.fileno())
f.close
p1=subprocess.Popen(["chmod","+x","/home/www-data/web2py/applications/fingerPrint/modules/classifier_stuff/cmd.sh"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout, stderr = p1.communicate()
output = p1.communicate()[0]
print('stdout:'+stdout+' stderr:'+stderr)
sys.stdout.flush()
p2=subprocess.Popen(["sudo /home/www-data/web2py/applications/fingerPrint/modules/classifier_stuff/cmd.sh"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout, stderr = p2.communicate()
print('stdout:'+stdout+' stderr:'+stderr)
sys.stdout.flush()
但我得到
stdout: stderr:
Traceback (most recent call last):
File "prepare_and_train.py", line 56, in <module>
p2=subprocess.Popen(["/home/www-data/web2py/applications/fingerPrint/modules/classifier_stuff/cmd.sh"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 26] Text file busy
如果我将PIPE改为STDOUT,我会得到一个有趣的
OSError: [Errno 9] Bad file descriptor
和相同的文件忙碌&#39;当我尝试subprocess.call时:
sudo: unable to execute ./cmd.sh: Text file busy
stdout: stderr:
我真的不在乎我是怎么做的,我只想要工作代码 - 这里有任何提示吗?我(很明显)对linux来说是新手
答案 0 :(得分:2)
您正在进行的错误正在发生,因为您正在尝试执行脚本,同时它仍处于打开状态以进行写入。特别是,请参阅以下最小示例:
#!/usr/bin/env python
import os
f = open('f.sh', 'w')
f.write("#!/bin/sh\necho test")
os.chmod('f.sh', 0o755)
os.execl('f.sh', './f.sh')
如果你执行它,你会得到:
$ ./a.py
Traceback (most recent call last):
File "./a.py", line 8, in <module>
os.execl('f.sh', './f.sh')
File "/usr/lib64/python3.4/os.py", line 491, in execl
execv(file, args)
OSError: [Errno 26] Text file busy
如果您确保在执行前关闭文件,例如:
#!/usr/bin/env python
import os
with open('f.sh', 'w') as f:
f.write("#!/bin/sh\necho test")
os.chmod('f.sh', 0o755)
os.execl('f.sh', './f.sh')
它工作正常:
$ ./a.py
test
进入您的具体问题,第6行:
f.close
您缺少括号,因此您只需获取(而不是使用)它,而不是调用close()
方法。那应该是:
f.close()
或者在我的示例中优先使用with
语句。
在此期间,您可能还想使用os.chmod()
而不是调用外部chmod
工具。
答案 1 :(得分:1)
“破损管道”错误是正常的,并且对于管道为head
或类似实用程序的任何内容都是预期的。
稍微分解一下,
当你没有大量输出时,(4)永远不会发生,所以你不会一直看到这个错误。但这是正常的和预期的。
无论如何,我会处理Python本身的head
部分。然后你也可以取消shell=True
。
find = subprocess.Popen(['find', rootDir + '/' + str(k), '-type', 'f'],
stdout=subprocess.PIPE)
result = [find.stdout.readline() for x in xrange(10)]
find.terminate()
with open('negatives' + str(i) + 'txt', 'w') as output:
output.write(''.join(result))
(-iname "*"
find
的{{1}}参数似乎没有任何用处,所以我把它遗漏了。)
具有讽刺意味的是,这在Python中比在“复杂”shell脚本中更不透明。当然,在纯Python中,您可以使用os.walk()
而不是find
。