en
ru
1 / 1

Метка: linux

  1. 4 июня 2016 Как сохранить копию вывода скрипта в лог

    В некоторых ситуациях бывает нужно перенаправить вывод в stdout и stderr из шел-скрипта в лог, сохранив его при этом и в терминале тоже. Обычно в таких случаях я заворачивал интересующие команды в фигурные скобки и перенаправлял полученную составную команду на вход tee. В скрипте ниже более прямой способ добиться того же самого результата с помощью именованных пайпов.

    #!/usr/bin/env bash
    
    # stdout и stderr будут перенаправлены в этот файл.
    log_file="script.log"
    
    # Завершить скрипт, если какая-либо из команд вернёт ошибку, которая не
    # будет обработана.
    set -e
    
    # Для создания временного пайпа нет специальной команды, так что заводим
    # временную директорию, в которую помещаем пайп.
    fifo_dir="$(mktemp -d)"
    fifo="${fifo_dir}/fifo"
    mkfifo "${fifo}"
    
    # Команда `tee` дублирует все данные, прочитанные из пайпа, и в stdout,
    # и в лог-файл.
    tee "${log_file}" < "${fifo}" & tee_pid=$!
    
    # Перенаправляем stdout и stderr в пайп.
    exec &> "${fifo}"
    
    cleanup() {
        # Запоминаем результат последней команды.
        code=$?
    
        # Разрешаем функции завершиться, даже если в процессе возникнет ошибка.
        set +e
    
        echo "Exiting with code ${code}"
    
        # Нужно закрыть дескрипторы stdout и stderr, чтобы процесс `tee`
        # завершился.
        exec 1>&- 2>&-
        wait ${tee_pid}
        rm -rf "${fifo_dir}"
    
        # Здесь можно сделать что-нибудь с получившимся лог-файлом, например:
        # cat "${log_file}" | mail -s "${log_file}" user@example.com
    
        exit ${code}
    }
    
    # cleanup() вызовется с правильным кодом возврата даже если скрипт будет
    # остановлен преждевременно из-за ошибки (см. `set -e` выше).
    trap cleanup EXIT
    
    # Здесь должно быть основное тело скрипта.
    # Нужно отметить, что, если процесс скрипта будет в какой-то момент
    # замещён командой `exec`, функция cleanup() не вызовется, и временные файлы
    # не будут удалены.
    $@
    

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

    Есть и другой способ получить аналогичный эффект, используя встроенную в bash команду coproc, который описан, например, здесь и обсуждение на связанную с coproc тему здесь. У него есть определённые преимущества (например, не нужен доступ на запись в директорию для создания временных файлов), но лично я продолжу использовать именованные пайпы, т.к. код с ними выглядит понятнее.

  2. 17 мая 2016 Исправляем вход в адимский интерфейс TP-LINK'а

    В TP-LINK'е сломали импорт настроек после обновления прошивки. На самом деле, его сломали уже довольно давно (как минимум, в 2014 году, судя по сообщениям с некоторых форумов), но я столкнулся с этой проблемой только недавно, обновив свой WDR3600. Я редко меняю прошивку роутера. Источником проблемы стало изменение способа хранения паролей: теперь они не хранятся в окрытом виде, вместо этого записывается некая хэш-сумма (что, само по себе, хорошо). В результате чего, после восстановления сбэкапленных настроек, пользователи потеряли возможность залогиниться в интерфейс роутера.

    Одно из возможных решений — сбросить роутер на заводские настройки и повторить кофигурирование по памяти, или списывая с заблаговременно сделанных скриншотов. Подходящих скриншотов у меня не оказалось, а перспектива перенастраивать форвардинг портов и привязку айпишников к MAC-адресам (для выдачи по DHCP) меня не обрадовала.

    Немного погуглив, я выяснил, что конфиг экспортируется в виде обычного текста, зашифрованного с помощью симметричного шифра (DES-ECB). К счастью, некие добрые люди уже провели надлежащие исследования, позволяющие его расшифровать. Раскодированный конфиг от старой прошивки состоит из ~1300 пар вида ключ-значение и выглядит примерно так:

    lan_ip 192.168.8.200
    lan_msk 255.255.255.0
    ...
    lgn_ousr admin
    lgn_opswd admin
    lgn_usr **********
    lgn_pwd **********
    ...
    

    Чтобы сконвертировать его обратно, в форму, пригодную для восстановления на роутере, нужно, перед шифрования с помощью того же самого шифра, записать в начало файла его MD5-сумму, а с конца дополнить нулевыми байтами до ближайшей восьмибайтовой границы. Я сделал удобный скрипт для автоматизации процесса кодирования/декодирования.

    ( tlrecode.sh )

    Для восстановления входа на роутер нужно:

    • сохранить настройки перед обновлением прошивки;
    • сбросить роутер до настроек по умолчанию (если оказалось, что после восстановления сохранённых настроек вход больше невозможен);
    • изменить логин/пароль на желаемые и сохранить новый конфиг;
    • декодировать оба конфига с помощью tlrecode.sh config.bin config.txt && tlrecode.sh config-new.bin config-new.txt;
    • исправить старый конфиг, заменив все строчки, начинающиеся с lgn_, на их вариант из нового конфига;
    • сконвертировать исправленный конфиг с помощью tlrecode.sh -e config.txt config-updated.bin;
    • восстановить настройки роутера, загрузив config-updated.bin.

    После завершения процесса обновления, вход с использованием выбранных логина и пароля не должен вызвать проблем.

  3. 5 сентября 2015 Как я перешёл на XFCE

    Мне действительно очень нравится Гном 3 за внешний вид и удобство. На самом деле, я разными версиями Гнома пользовался, как минимум, со времён 1.2, когда ещё в качестве оконного менеджера с ним шёл Enlightenment. Однако, после недавнего обновления до 22ой Федоры, многие вещи начали слишком уж раздражать. Например, иногда им начинает съедаться 100% одного из ядер процессора, иногда расширения самопроизвольно выгружаются, и некоторые привычные расширения так и не оказываются обновлёнными до текущей версии Гнома, и дисплейный менеджер зачем-то постоянно загружен, и т.д. Это всё сподвигло меня наконец-то переключиться на нечто более простое и лёгкое.

    Я и так уже пользовался xfce4-panel в качестве сайдбара под Гномом, так что перейти именно на XFCE было логичным. Здесь я постарался воссоздать привычное окружение, с примерно следующим результатом:

    top, запущенный в gnome-terminal, и Midnight Commander с темой xoria256, запущенный в xterm

    top, запущенный в gnome-terminal, и Midnight Commander с темой xoria256, запущенный в xterm

    ( ещё пара скриншотов и кучка патчей )

    В общем, результатом я вполне доволен. Вот, для сравнения, скриншот до, с использованием третьего Гнома:

    Гном с аналогичными настройками

    Гном с аналогичными настройками

    Разница по сравнению со скриншотами после не так велика, но в этом и была вся задумка.