Бинарные часы на bash

Раз пошла такая пьянка (в смысле, раз уж день программиста), я на радостях решил не останавливаться на достигнутом и написать что-нибудь ещё на Bash.

Bash Binary Clock (9.50КиБ)

Бинарные часы — популярное сейчас развлечение программистов, вроде написания игры «Жизнь». Как можно догадаться из названия, они показывают время в двоичной системе исчисления. Самое интересное в моей реализации — как подавляется ввод клавиатуры, это неочевидно. Всё дело в следующих строчках:
# Нажатие «Enter» нужно отключать отдельно
bind -r '\r'
# Сохраняем предыдущее состояние
ORIG=`stty -g`
# Отключаем остальную клавиатуру
stty -echo
# На выходе всё нужно восстановить как было
function Restore {
    stty "$ORIG"
    bind '"\r":accept-line'
}

trap 'Restore' EXIT
Наверняка не раз ещё пригодится. Сама программа бинарных часов дальше, там у меня несколько сложнее, так как я ещё убираю с экрана курсор, чтобы не мешался. Выйти из программы просто — надо нажать Ctrl-C.
#!/bin/bash

declare -a xy

# Выключаем Enter
bind -r '\r'
# Выключаем остальную клавиатуру
ORIG=`stty -g`
stty -echo

function Restore {
    stty "$ORIG"
    bind '"\r":accept-line'
    echo -ne "\033[5B\033[?25h\033[m"
}

trap 'Restore' EXIT

# Цвета наших «стрелок»
colors=(30 34)

# Очистка графического массива
function Clear {
    xy=
}

# Подготовка маски одного разряда
function Print {
    mask=$(printf '%08d' `echo "obase=2; $1" | bc`)
    let pos="$2*4"

    for x in {0..1}; do
        for y in {0..3}; do
            xy[$pos+$x+$y*100]=${mask:$x*4+$y:1}
        done
    done
}

# Печать часов на экран
function PrintClock {
    echo -e "\033[?25l\033[1mBash Binary Clock by Evgeny Stepanischev\033[0m\n"

    for y in {0..3}; do
        for x in {0..9}; do
            c=${colors[${xy[$x+$y*100]:-0}]}
            echo -ne "\033[${c}m▣"
        done
        echo -e "\033[0m"
    done

    # после печати часов передвигаем курсов так,
    # чтобы следующий кадр выводился поверх предыдущего
    echo -en "\033[8A"
}

# Вывод часов
function Clock {
    Clear
    for i in {0..2}; do
        Print $1 $i
        shift
    done

    PrintClock

    echo -e "\n"
}

while true; do
    Clock `date "+%H %M %S"`
    sleep 1
done
Я писал под «Мак», так что на других системах может и не завестись.
13 сентября 2011 20:09

dinoel (инкогнито)
14 сентября 2011, 03:41

Тупо скопипейстил, не работает (ubuntu 10). Выложи файлом, интересно :)

bolk (bolknote.ru)
14 сентября 2011, 06:41, ответ предназначен dinoel

Я под «Мак» это всё делаю, может и не работать где-то :) Вот, на 10 дней ссылка: http://zalil.ru/31696117

bolk (bolknote.ru)
14 сентября 2011, 08:17, ответ предназначен dinoel

Посмотрел на CentOS, работает. Терминал ANSI-цвета поддерживает, запускаешь через *bash* (не через sh)?

http://about.me/rembish (инкогнито)
14 сентября 2011, 10:49

Ubuntu 10.04 работает.
Дело в bash, sh такое не тянет.

ks1v (инкогнито)
14 сентября 2011, 20:51

Тупо скопипейстил, работает (ubuntu 11.04) (=

maks_sergeich (инкогнито)
10 января 2012, 03:47

Спасибо, все работает
linux mint 12

maks_sergeich (инкогнито)
10 января 2012, 03:48

Спасибо, все работает
linux mint 12

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)