2013-02-20 3 views
1

От какого-то Googling (я не эксперт по bash каким-либо образом), я смог собрать сценарий bash, который позволяет мне запускать тестовый набор и выводить строку состояния внизу, пока она работает. Обычно это занимает около 10 часов, а строка состояния сообщает мне, сколько тестов прошло и сколько провалилось.Как этот сценарий bash приводит к бесконечному циклу?

Он отлично работает иногда, однако иногда я сталкиваюсь с бесконечным циклом, который является плохим (mmm-kay?). Вот код, я использую:

#!/bin/bash 
WHITE="\033[0m" 
GREEN="\033[32m" 
RED="\033[31m" 

(run_test_suite 2>&1) | tee out.txt | 
while IFS=read -r line; 
do 
    printf "%$(tput cols)s\r" " "; 
    printf "%s\n" "$line"; 

    printf "${WHITE}Passing Tests: ${GREEN}$(grep -c passed out.txt)\t"   2>&1; 
    printf "${WHITE}Failed Tests: ${RED}$( grep -c FAILED out.txt)${WHITE}\r" 2>&1; 
done 

Что происходит, когда я сталкиваюсь с ошибкой является у меня будет сообщение об ошибке повторения бесконечно, в результате чего файл журнала (out.txt), чтобы стать некоторые мульти-мегабайтный уродство (я думаю, он попал в ГБ один раз). Вот пример ошибки, которая повторяется (с четырьмя линиями пробелов между каждым набором):

warning caused by MY::Custom::Perl::Module::TEST_FUNCTION 
print() on closed filehandle GEN3663 at /some/CPAN/Perl/Module.pm line 123. 

я пытался вынимая 2>&1 редирект, и я попытался изменить while IFS=read -r line; к while read -r line;, но я получаю бесконечное петля. Что странно, похоже, это происходит большую часть времени, но были случаи, когда я заканчивал длинный набор тестов без каких-либо проблем.

EDIT:

Причина Я пишу это, чтобы обновить из черного & белого тестового набора для цветной кодировкой набора тестов (следовательно, коды ANSI). Раньше я бы запустить тестирование с использованием

run_test_suite > out.txt 2>&1 & 
watch 'grep -c FAILED out.txt; grep -c passed out.txt; tail -20 out.txt' 

Забегая таким образом получает такое же предупреждение от Perl, но выводит его в файл и движется дальше, а не застрять в бесконечном цикле. Используя часы, также печатает материал, например, [32m, вместо того, чтобы нарисовать текст как зеленый.

+0

Что ручка печатается на ? – ikegami

+1

И по какой причине вы должны верить, что в 'tee' есть ошибка? Какой у вас показатель, что проблема не в наборе тестов? – tripleee

+2

вы в настоящее время присваиваете значение 'read' IFS и пытаетесь запустить команду с именем' -r' с аргументом строки. Также расширение значений (особенно командного вывода) в первый аргумент 'printf' не является хорошей идеей. У вас наверняка есть ошибка в 'run_test_suite', это не связано с' tee'. – ormaaj

ответ

0

Я смог исправить ошибки perl, и скрипт bash, похоже, теперь хорошо работает после нескольких модификаций. Тем не менее, кажется, что это будет более безопасным способом, чтобы запустить тестовый набор в случае что-то подобное должно было случиться в будущем:

#!/bin/bash 
WHITE="\033[0m" 
GREEN="\033[32m" 
RED="\033[31m" 

run_full_test > out.txt 2>&1 & 
tail -f out.txt | while IFS= read line; do 
    printf "%$(tput cols)s\r" " "; 
    printf "%s\n" "$line"; 

    printf "${WHITE}Passing Tests: ${GREEN}$(grep -c passed  out.txt)\t"   2>&1; 
    printf "${WHITE}Failed Tests: ${RED}$( grep -c 'FAILED!!' out.txt)${WHITE}\r" 2>&1; 
done 

Есть некоторые минусы этого. В основном, если я ударил Ctrl-C, чтобы остановить тест, он, похоже, остановился, но на самом деле run_full_test все еще работает в фоновом режиме, и мне нужно помнить, что нужно его убить вручную. Также, когда тест закончен, tail -f все еще работает. Другими словами, здесь работают два процесса, и они не синхронизированы.

Вот оригинальный сценарий, слегка модифицирована, в котором рассматриваются эти проблемы, но не является надежным (т.е. может застрять в бесконечном цикле, если run_full_test имеет проблемы):

#!/bin/bash 
WHITE="\033[0m" 
GREEN="\033[32m" 
RED="\033[31m" 

(run_full_test 2>&1) | tee out.txt | while IFS= read line; do 
    printf "%$(tput cols)s\r" " "; 
    printf "%s\n" "$line"; 

    printf "${WHITE}Passing Tests: ${GREEN}$(grep -c passed  out.txt)\t"   2>&1; 
    printf "${WHITE}Failed Tests: ${RED}$( grep -c 'FAILED!!' out.txt)${WHITE}\r" 2>&1; 
done 
+0

Это достаточно хорошо, но если у кого-то есть лучший ответ, который затрагивает обе проблемы (выполняется в одном процессе и не является хрупким, что может произойти в 'run_full_test'), что было бы очень оценено – redbmk

0

Ошибка в вашем скрипте. Это не ошибка ввода-вывода; это незаконная ошибка аргумента. Эта ошибка возникает, когда переменная, которую вы предоставляете в качестве дескриптора, не является дескриптором вообще или является той, которую вы закрыли.

Записи отбитых результатов труб в процессе гибели от SIGPIPE или print возвращения ложного $! набора для EPIPE.

+0

Скрипт 'run_test_suite' работает сам по себе (и по-прежнему получает ошибку дескриптора файла), но я хочу, чтобы оба (A) сохраняли вывод в текстовом файле и (B) отображали его в реальном времени (в цвете) со статусом line – redbmk

+0

Вопрос, который вы задали, касается некоторого бесконечного цикла. Если у вас есть проблемы с сохранением вывода или отображением чего-то в цвете, вы должны задать другой вопрос. – ikegami

+0

Если вам нужна дополнительная помощь в решении вашей проблемы, вам придется предоставить некоторую информацию об этом. Мы не можем вам помочь, если вы настаиваете на том, чтобы отвлечься от того, где находится проблема. – ikegami