xT 10.05.2011 21:57

Скрипты на bashТроббер для длительных операций


Набрасывая очередной мелкий баш-скрипт на коленке озадачился тем, чтобы у относительно длительных операций отображался индикатор действия\выполнения, он же троббер.

Придумывать ничего сам не стал и обратился к гуглу. Собственно, вот что нашлось:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
spinner()
{
local pid=$1
local delay=0.75
local spinstr='|/-\'
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}

Коротко о том, как это работает:

Более подробно можно прочитать пройдя по ссылке в заголовке.


Как применять в скрипте:
1
2
(a_long_running_task) &
spinner $!


Как результат:
Bash Throbber


Тэги: bash throbber
+ 16 -
Похожие Поделиться

Zend 15.05.2011 00:12 #
Красота ;-)
sagod 15.05.2011 01:24 #
Спасибо :)
В тему будет сказано, есть замечательный алиас к alert для отображения всплывающего сообщения в области уведомлений NotifyOSD по окончании работы какого-либо скрипта: http://aonick.livejournal.com/12401.html
ananas 15.05.2011 11:26 #
место жуткого пайпа в while проще использовать

while kill -0 $pid; do
kstep 15.05.2011 23:14 #
Слушай, огромное спасибо! До сих пор этого не знал.
ananas 15.05.2011 23:15 #
да не за что
cppmm 16.05.2011 16:25 #
Хорошо, конечно, но с многопоточным софтом не справляется. Я как-то писал скрипт для мониторинга emerge(когда на компе идёт компиляция, а я за буком сижу и по ssh вижу, какой пакет и сколько компилится). Так вот до сих пор не знаю, как решить проблему с тем, что в ps два процесса emerge(один качает исходники, второй компилит уже скачанное).
kstep 17.05.2011 06:00 #
Разграничивать по cmdline, выдирая данные из /proc//cmdline например?
kstep 17.05.2011 06:00 #
* /proc/${pid}/cmdline
cppmm 17.05.2011 12:36 #
Выдрать данные не проблема и без проц. Как скрипт узнает, из какого PID'а брать данные, если есть два процесса emerge одновременно и у каждого свой PID?
Ну или не emerge. Что угодно. Любая многопоточная программа. Банальный скрипт какой-нибудь на перле, скачивающий в несколько потоков что-нибудь с инета. Будет 10 процессов perl scriptname.pl и у каждого свой pid.
kstep 17.05.2011 17:30 #
min(pids)?
cppmm 18.05.2011 12:43 #
Это идея. Спасибо.
philosoft 19.06.2011 00:29 #
Вместо такого монструозного while можно обойтись
1
ps -eo pid | grep $pid
Вместо двух printf и извратов со временными переменными можно обойтись
1
for i in \| / - \\; do printf ' [%c]\b\b\b\b'; sleep $delay; done
Ну и delay=0.25 мне больше нравицо ☺
philosoft 19.06.2011 00:35 #
Вообщем вот версия получше
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
spinner()
{
    local pid=$1
    local delay=0.25
    while [ $(ps -eo pid | grep $pid) ]; do
        for i in \| / - \\; do
            printf ' [%c]\b\b\b\b' $i
            sleep $delay
        done
    done
    printf '\b\b\b\b'
}
darkrain 19.06.2011 16:06 #
Спасибо! Как раз пригодилось для свежего скрипта