Я пытаюсь отладить программу, которая генерирует много данных. Но событие, которое я хочу отладить, происходит через случайное количество времени (я не могу его форсировать). Поэтому мне нужно было бы увидеть stdout и stderr в моей оболочке и сохранить тот же вывод в файл для дальнейшего анализа и прерывания, как только я увижу то, что мне нужно в выводе моей оболочки.

Я нашел команду script в этой ветке Ask Ubuntu, но не могу заставить ее работать, скрипт говорит:

$ script "./client -p 4242 -n test"
Script started, output file is ./client -p 4242 -n test

и затем выходит. Файл содержит:

Script started on Thu Jun 26 13:51:12 2014

Script done on Thu Jun 26 13:51:12 2014

Так что script не работает. Файл ./client является скриптом Python. Я также попытался запустить его с $ python client -p 4242 -n test но он тоже не работает.

Я также видел в том же потоке некоторые ответы с tee и pipe, но я не могу получить его для вывода на мою оболочку и посмотреть, что происходит:

$ ./client -p 4242 -n test | tee output.log

дает мне курсор ожидания без ничего. Так что tee не работает.

Есть ли какое-то другое решение, или я обречен подождать и прервать программу через некоторое время и надеяться, что она прошла через событие, которое я ищу?

Большое спасибо за вашу помощь!

PS Я на zshell (с oh-my-zsh), Mac OSX 10.9.3, Python 2.7.5

РЕДАКТИРОВАТЬ: я могу упомянуть, что я использую модуль multiprocessing и сценарий ./client запускает несколько других Process . Может ли это быть по этой причине? Тем не менее, я не понимаю, почему он не перехватит вывод процесса ./client ...

EDIT2: я попробовал ответ от Маттео ниже (большое спасибо за вашу помощь), и он продолжает становиться все более и более странным:

Если процесс завершается ошибкой (сервер выключен), я вижу вывод:

$ ./client -p 4242 -n test 2>&1 | tee output.log
Process Process-1:
Client # 1: Could not connect to server. Stopping.
Spawner: New client # 1 started...
Done.
$

но если похоже, что он работает, я ничего не вижу

$ ./client -p 4242 -n test 2>&1 | tee output.log
^C [voluntary interrupt after a lot of waiting]
$ cat output.log
$ 

В приведенном выше журнале (где он выходит из строя) вы можете видеть, что новый процесс печатается раньше основного (Spawner), даже если он запущен после него. Так что это похоже на действительно странную магию вывода.

2 ответа2

2

Вы можете перенаправить стандартную ошибку на стандартный вывод, а затем использовать tee для дублирования стандартного вывода и сохранения его в файле.

$ ./client -p 4242 -n test 2>&1  | tee output.log

Изменить: вы можете попробовать команду

$ ( echo "stdout" ; echo "stderr" 1>&2 ) 2>&1  | tee output.log

Два echo выводят как на stdout, так и на stderr. Вы должны увидеть и то, и другое в output.log

редактировать

Вместо изменения вашей программы (сбрасывать) вы также можете попробовать script -q или несколько других инструментов, как указано в разделе Отключение буферизации в конвейере.

1

Победа!

Как уже упоминалось в вопросе, я использовал многопроцессорность Python .Процесс для порождения новых процессов от основного клиента. Из-за этого выходные данные были буферизованы и ожидали заполнения буфера перед сбросом, но кажется, что это никогда не происходит с | тройник команда. Таким образом, никогда ничего не печатать и ждать бесконечно.

Таким образом, решение состоит в том, чтобы добавить sys.stdout.flush() после каждого оператора print как упомянуто здесь:

print "Player # " + int(self.id) + " joined the map"
sys.stdout.flush() #<==== THIS MAKES IT ALL WORK !

После этого ответ Matteo работает как талисман, и можно одновременно выводить текст в оболочке и в текстовом файле.

$ ./client -p 4242 -n test 2>&1  | tee output.log`
$ cat output.log
Player # 1 joined the map.
Player # 1 updated it's inventory.
[...]

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .