2016-06-19 3 views
2

Мне удалось показать индикаторы прогресса, пока определенные процессы выполняются до тех пор, пока они не закончатся, но я не смог получить код, чтобы показывать тот же индикатор прогресса, когда я запускаю некоторое время петля. Например, я делаю это, когда я пинг внутри сценария:Bash script: Показывать индикатор прогресса до тех пор, пока цикл цикла не завершится

/bin/ping -c 10 $ipaddress > /pinglog & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
printf "] " 

Я могу также показать прогресс с помощью команды сна внутри сценария:

sleep 30 & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
printf "." 
sleep 1 
done 
printf "] " 

Оба этих примера работы и мой вывод выглядит это:

[.........................} 

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

while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
printf "] " 
do 
sleep 5 
done 
echo $VAR1 was found 

Это работает, однако он не останавливается, когда строка найдена, и результат выглядит следующим образом:

[.] [.] [.] [.] [.] and on and on... 

Я попытался двигаться фактическое время цикла делать, сон 5 и сделано выше первого printf, но результаты хуже, и я даже не получил выход индикатора прогресса. Как я могу исправить это, чтобы получить тот же индикатор прогресса, что и мои первые 2 примера, и он останавливается, когда мой шаблон найден?

ответ

0

Я решил проблему. Чтобы иметь выходной формат [........], вы должны запустить первый printf «[» до начала первого цикла.Затем поставьте команду sleep 5 в фоновом режиме и используйте второй цикл while на своем PID вместо самого исходного цикла while, потому что мы хотим убить команду sleep 5, а не цикл while. Это позволит повторяющимся точкам повторяться внутри скобок каждую секунду вместо каждых 5 секунд и разрешать поиск строки поиска. Наконец, поместите последний printf "]" за пределами последнего, выполненного для завершения форматирования после того, как цикл while завершится для строки поиска. Это предотвращает повторение [.] Каждые пять секунд. Это то, что сработало для меня:

printf "[" 
while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] 
do 
sleep 5 & PID=$! 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
done 
printf "] " 
echo $VAR1 was found 
1

Команда, прошедшая проверку while, является последней командой до do. Итак, ваша петля в основном while ...; printf "] "; do ... ; end, и так как printf никогда не сбой, while никогда не закончится.

Непонятно мне, что вы ожидаете проверить с помощью петли while. Если ожидание заключается в том, что составная команда [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] & будет протестирована, вы должны знать, что при запуске команды в фоновом режиме код состояния отражает только то, удалось ли bash разблокировать дочерний элемент для запуска фоновой команды (которая почти всегда дело). Код состояния команды недоступен до тех пор, пока команда не завершится, поэтому более или менее бессмысленно запускать ее в фоновом режиме, если вы хотите только проверить код состояния.

Вы можете создать целую петлю while, если это то, что вы надеетесь сделать; поместите & после done, который завершает составной оператор while. Это, вероятно, то, что вы на самом деле ищете:

printf "[" 
while ! grep -wqm1 "$VAR1" logfile; do 
    sleep 1 
done & 
while kill -0 $! 2>/dev/null; do 
    printf "." 
done 
printf "] " 

Примечание: -q вариант grep заставляет его производить только возвращение статуса. (При этом изменении -m1 на самом деле избыточно.) Это позволяет избежать использования [[ для проверки вывода. Если вы на 100% не уверены, что $VAR1 не может содержать пробелы или метасимволы оболочки, вы должны окружать расширение кавычками. Нет необходимости хранить $! в переменной, так как она будет продолжать содержать то же значение, пока вы не воспользуетесь какой-либо другой командой.

+0

Я проверяю, существует ли шаблон в определенном файле журнала, используя цикл while. Пока я жду появления шаблона, я хочу показать индикатор прогресса, как я представил в своих первых двух примерах, используя другой цикл while. Так что вложенная петля так сказать. Принтер [......] должен остановиться, когда появится шаблон. – user53029

+0

Просто прочитайте, что вы сказали. Однако printf будет/должен завершиться с ошибкой/завершить/независимо ... когда PID для начального цикла while завершается (когда шаблон найден). Но это не так. По крайней мере, не с этим кодом. – user53029

+0

@ user53029: 'printf' не подведет. Почему это должно быть? – rici

Смежные вопросы