2016-10-21 3 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', 'export', 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, так Трассирование вероятно вне. Не повезло, вам просто нужно написать фактический 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

Можете ли вы запустить приведенный здесь пример, без изменений? Работает ли это для вас ? Следующий ting - изменить имя файла на UNC-путь, как это делает ваш исходный код. Он все еще работает? – nos

+0

Там все еще загружаются не минимальные вещи: выведите все это и посмотрите, работает ли действительно минимальный пример (только вызов подпроцесса open и toy sample).Если это так, добавьте еще одну вещь и посмотрите, не по-прежнему ли она работает - может быть, svn делает что-то необычное, попробуйте '['svn', 'ls']' или что-то тривиальное и добавьте детали, пока он не перестанет работать снова. – Useless

-5

попробовать это:

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