Download - Romanova techforum bash
BashСборник рецептов
● Все администраторы делают это
● Позволяет избавиться от рутинной работы
● Всё готово — велосипеды не нужны
● Простота использования
for i in *mp3; do mv "$i" "$(mp3info -p "%a - %t" "$i" | iconv -f cp1251 -t utf-8)"done
Зачем нужно писать скрипты?
zcat query-log.gz | cut -f 2 | sort | uniq -c | sort -rn
● Поиск и исправление ошибок — та же рутина
● There is not only one way
● Иногда оно работает. Но как?!
for i in *mp3; do mv "$i" "$(mp3info -p '%a - %t.mp3' "$i" | iconv -f cp1251 -t utf-8)"done
Зачем знать bash хорошо?
zcat query-log.gz | cut -f 2 | sort | uniq -c | sort -rn
Процессы в Unix'е
● fork — создает копию процесса
● exec — замена одного процесса другим
● Переменные окружения
● Статус возврата
● Файловые дескрипторы 0, 1 и 2
● Права процесса
родитель потомок(копия)
fork
новый процесс
exec
родитель
wait
exit
2. Считаем количество файлов в каталоге:
Пара примеров для разминки1. Меняем системный конфиг:
tr@serv$ sudo cat rc.conf > /etc/rc.confbash: /etc/rc.conf: Permission denied
tr@serv$ cat rc.conf | sudo tee /etc/rc.conftr@serv$ sudo sh -c 'cat rc.conf > /etc/rc.conf'
tr@serv$ count=0tr@serv$ cat f | while read name val; do count=$((count + val)); donetr@serv$ echo $count0
Bash как язык программирования
● Переменные
● Управляющие конструкции: условия, циклы, выбор
● Арифметические и логические выражения
● Функции
● «Библиотека» — набор встроенных и сторонних команд
tr@serv$ time for i in {1..10000}; do echo "hello"; done > /dev/null...sys 0m0.007s tr@serv$ time for i in {1..10000}; do /bin/echo "hello"; done > /dev/null...sys 0m8.587s
Задачка на сегодня
Почему bash?
● Быстрая разработка
● Много работы с файлами
● Большая часть утилит готова, нужно только собрать
Организовать тестирование программ, присылаемых пользователями
Начнем с простогоЕсть исполняемый файл и каталог с тестами, нужно запускать тесты до первой неудачи
● Соглашение: тесты — *.t, ответы — *.a
● Нужен цикл по всем тестам: for t in *.t; do echo $t; done ls *.t | while read t; do echo $t; done
● И условный оператор для сравнения результата с ответом: $PROG < $t > $out if diff $out $ans; then echo "error"; exit 1; fi
Переменные
● Присваивание без пробелов!
● Отсутствие типизации
● Специальные переменные
● Области видимости
● Команда export
tr@serv$ x = 0x: command not found tr@serv$ echo $?127tr@serv$ if $?; then echo 'err'; fi0: command not found tr@serv$ x=0; bash -c 'echo #$x#'x=##
Массивы music=(*.mp3) echo ${music[$RANDOM%${#music[@]}]}
Волшебные скобки
● Замена
t=1.t; a=${t/.t/.a}; echo $a # 1.afor i in ${PATH//:/ }; do echo $i; done
OBJ=${SRC%.c}.oext=${filename##*.}
log=2012-04-17-queries.txt; month=${log:5:2}; echo $month; # 04
● Подстроки
● Суффиксы-префиксы
● Смена регистра var=upper; echo ${var^^} # UPPERvar=LOWER; echo ${var,,} # lower
Продолжаем: компиляция
Нужно создать из текста программы исполняемый файл
● Соглашение: обрабатываются файлы *.c, *.cpp, *.py
● Для выбора способа обработки используем case
● Подключаем конфиг с нужными переменными
● Используем косвенные ссылки на переменные
● Делаем программу на Питоне исполняемой
Формулируем условия короче● Стандартный способ — проверка статуса возврата
● Команда test (она же [)
● [[ и ((
● set -e
if test -e file; then echo "exists"; fi ● Сокращенные вычисления
touch "/bin/I'm root" 2>/dev/null || echo "I'm not root" [ 1 -eq 2 -a -n "`echo -n + >&2`" ]; echo $? # +1
Полезная команда find
● Поиск всех файлов по определенному критерию:
○ по шаблону
○ по времени
○ по размеру
○ по типу
● Выполнение команды для всех результатов● find + xargs
Собираем всё вместе
Нужно обработать все файлы из очереди
● Используем различные виды условий
● Пишем вспомогательные функции
● Создаем необходимые файлы и каталоги
● Запускаем компиляцию и проверку с записью
результатов в лог
Последние штрихи
● Развертывание системы:
○ создание нужных каталогов
○ генерация конфига
● Обработка сигналов
● Запуск сторонних программ с ulimit'ом
● Отладка и тестирование
● Документация
Демонизация скрипта
● Запуск программы в фоновом режиме
● Управление задачами
● crontab и flock/lockf
● Утилита nohup
● Закрываем ввод, вывод и вывод об ошибках
● Бонус-трек: использование screen и tmux
Команды для обработки текстов● Выбор определенного поля cut, awk, sed
● Подсчет статистики sort (-rnkcm), uniq
du -k * | awk '{sum += $1} END {print sum }' du -k * | cut -f 1 | (sum=0; while read x; do let sum+=x; done; echo $sum)
● Замена подстрок с помощью sed
● Поиск в тексте: grep, zgrep
sed 's#<[^>]*>\([^<]*\)</[^>]*>#\1\t#g' table.html
grep -v -E '^\ *#|^$' test.txt | ./a.out
du --max-depth 1 -k /home | sort -rn | head
Обрабатываем логи и строим графики
● Сколько задач сдается в день
● Распределение ошибок по типам
● 10 лучших участников
● Самое простое и самое сложное задание
Что хотим знать?
Как это сделать?
● Используем утилиты для обработки логов
● Строим графики и диаграммы в gnuplot'е
Итоги
+ Быстрая разработка
+ Автоматизация простых задач
+ Утилиты для обработки текстов
+ Легко комбинировать команды
— Местами неочевидный синтаксис — Может медленно работать — Нет сложных структур данных, объектов, работы с графикой и т. п.
Что почитать?
● bash Cookbook by Carl Albing, JP Vossen & Cameron Newbam
● man bash / man sh
● Advanced Bash-Scripting Guide by Mendel Cooper