2016-10-21 65 views
1

我有一个是被反复调用,并通过subprocess错误数据写入日志文件的功能,但是,每当新的数据写入到文件中,旧数据已清除。所以它不会在旧数据中附加任何新数据。开放(文件,“A +”)为f不附加

我做如下:

error_file = '\\\\some\\unc\\path\\error.log' 

class Node: 
    def __init__(self, path, rev): 
     self.path = path 
     self.rev = rev 

    def __hash__(self): 
     return hash((self.path, self.rev)) 

    def __eq__(self, node): 
     return (self.path, self.rev) == (node.path, node.rev) 

    def __ne__(self, node): 
     return not(self == node) 

def get_excluded_nodes(excludes_dir): 
    nodes = list() 
    for root, subdirs, files in os.walk(os.path.dirname(excludes_dir)): 
     if 'flagged' in files: 
      with open(os.path.join(root, 'flagged')) as f: 
      for line in f.readlines(): 
       try: 
        comps = line.split(' -a') 
        path = comps[0].strip() 
        rev = comps[1].split(':')[0].strip() 
        Nodes.append(Node(path,rev)) 
       except: 
        pass 
    return nodes 

def export_node(node, path=archive_dir): 
    with open(error_file, 'a') as f: 
     try: 
      comps = node.path.split('/') 
      if '.' in comps[len(comps)-1]: 
       os.makedirs(os.path.join(archive_dir, '/'.join(comps[:-1]))) 
      else: 
       os.makedirs(os.path.join(archive_dir, node.path)) 

      subprocess.call(['svn', 'export', os.path.join(some_path, node.path), another_path)], stderr=f) 
     except: 
      pass 


def remove_duplicate_nodes(nodes): 
    return set(nodes) 

if __name__ == '__main__': 
    all_nodes = get_excluded_nodes(os.path.realpath(__file__)) 
    nodes = remove_duplicate_nodes(all_nodes) 
    for node in nodes: 
     export_node(node) 

为什么不这项工作?

+0

@Chris_Rands我也试过。这也是一样的。 –

+0

我试过你的代码(修改刚好足以实际运行的东西),它工作正常。你确定'my_program'不是像你的文件那样写'\ r'等字符,当你看到它时会使输出看起来错误吗? – FatalError

+0

@FatalError'my_program'其实,'[ '的svn', '出口',SOME_PATH,another_path]' –

回答

2

仍然不是MVCE:它是不是最小的(什么是节点的,它如何影响追加到一个文件?),它是不完整的(其中是get_excluded_nodes?)。由于它不完整,因此也无法验证。

与最小的代码应该做同样的事情,你的榜样的MVCE,并能正常工作。

import subprocess 

def test(filename): 
    with open(filename, 'a') as f: 
     subprocess.call(['bash', '-c', 'echo $$ >&2'], stderr=f) 

if __name__=='__main__': 
    for _ in range(2): 
     test('stderr.log') 

这不你想要什么:

$ python stderr.py 
$ cat stderr.log 
344 
345 

$ python stderr.py 
$ cat stderr.log 
344 
345 
366 
367 

编辑我看到你在Windows上,所以strace的可能了。运气不好,你只需要写一个实际的MVCE。


也许在strace下运行你原来的(真实的,有种类的)脚本,看看有什么不同。作为参考,此脚本显示:

$ strace -f -e trace=open,dup2,lseek,write python stderr.py 

open("stderr.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3 
lseek(3, 0, SEEK_END)     = 28 
strace: Process 567 attached 
... 
[pid 567] dup2(3, 2)     = 2 # stderr=f 
... libc, locale stuff ... 
[pid 567] dup2(2, 1)     = 1 # >&2 
[pid 567] write(1, "567\n", 4)  = 4 
+0

我的最新更新如何?正如我所提到的,我很抱歉我没有一个完整的MVCE,因为我认为可能有一些简单的事情是我在原始代码片段中做错了。 –

+0

你可以运行这里给出的例子吗?对你起作用吗 ?下一步是将您的原始代码的文件名更改为UNC路径。它仍然有效吗? – nos

+0

那里还有很多非最小的东西:全部拿出来看看是否有一个非常小的例子(只是开放和一个玩具样本子流程调用)。如果确实如此,请添加一件事,看看它是否仍然存在不当行为 - 也许svn做了一些不寻常的事情,尝试'['svn','ls']'或者一些琐碎的事情,并添加细节,直到它再次停止工作。 – Useless

-5

试试这个:

with open(error_file, 'a+') as f: 
    print([my_program], file=f)