#python
#python
Вопрос:
Я пишу программу для агрегирования строк вывода strace на хосте Linux. Когда strace запускается с опцией «-f», он будет смешивать системные вызовы, поэтому:
close(255 <unfinished ...>
<... rt_sigprocmask resumed> NULL, 8) = 0
<... close resumed> ) = 0
[pid 19199] close(255 <unfinished ...>
[pid 19198] <... rt_sigprocmask resumed> NULL, 8) = 0
[pid 19199] <... close resumed> ) = 0
Я хотел бы выполнить итерацию по выводам и объединить «незавершенные» строки с «возобновленными» строками. Итак, в выводе над следующими двумя строками:
close(255 <unfinished ...>
.....
<... close resumed> ) = 0
Будет объединен в:
close(255) = 0
Я думал о том, чтобы разделить «незавершенные» строки на «>» и поместить их в список. Если бы будущая строка содержала резюме, я бы перебрал этот список, чтобы увидеть, присутствуют ли системный вызов и pid. Если бы они были, я бы разделил () строку на «>» и объединил их. Любопытно, есть ли лучший способ сделать это?
* Обновить *
Спасибо за потрясающий отзыв! Я придумал следующее и хотел бы узнать ваши мысли о коде:
holding_cell = list()
if len(sys.argv) > 1:
strace_file = open(sys.argv[1], "r")
else:
strace_file = sys.stdin
for line in strace_file.read().splitlines():
if "clone" in line:
print line
if "unfinished" in line:
holding_cell.append(line.split("<")[0])
elif "resumed" in line:
# Get the name of the system call / pid so we can try
# to match this line w/ one in the buffer
identifier = line.split()[1]
for cell in holding_cell:
if identifier in cell:
print cell line.split(">")[1]
holding_cell.remove(cell)
else:
print line
Есть ли более питонический способ написать это? Еще раз спасибо за отличные отзывы!
Комментарии:
1. Почему бы не прочитать его построчно, когда вы видите незаконченную строку, сохраните ее в отдельном буфере, иначе напишите свой буфер, когда вы увидите законченную строку, соответствующую этой незаконченной строке, чем объединить ее, записать и очистить буфер, таким образом, вы могли бы управлять несколькими незавершенными / завершенными блоками
2. На самом деле это то, чем я сейчас занимаюсь. Приношу свои извинения за то, что не разъяснил этот момент. Мне в основном любопытно, какие типы параметров буфера доступны и как эффективно сопоставить их.
3. Вы не должны публиковать свое решение внутри вопроса. Если он достаточно отличается от приведенного ответа, опубликуйте его как самостоятельный ответ. Если это получено из кода tdelaney, примите его ответ. Обзор кода — обсуждение того, как рабочий код можно было бы написать лучше, — лучше всего задавать на Code Review .
Ответ №1:
Некоторые итераторы, такие как файловые объекты, могут быть вложенными. Предполагая, что вы читаете это из объекта, подобного файлу, вы можете просто создать внутренний цикл для объединения. Я не уверен, каковы правила форматирования для strace
журналов, но номинально это может быть что-то вроде
def get_logs(filename):
with open('filename') as log:
for line in log:
if "<unfinished " in line:
preamble = line.split(' ', 1)[0].strip()
for line in log:
if " resumed>" in line:
yield "{}) = {}n".format(preamble,
line.split('=')[-1].strip())
break
else:
yield line
Комментарии:
1. Спасибо за потрясающий отзыв.