Перевод книги по написанию сценариев на BASH
Надоело смотреть историю bash - там нет пояснений - что и для чего использовалось. Поэтому решил создать данную страничку.
Тут я и буду располагать рецепты, которые по моему мнению стоит запомнить.
Есть список хостов list.txt , копируем файл виртуалхоста site.sbm-bio.net в файлы новых хостов, затем односторочным скриптом заменяем внутри этих файлов значения директив DocumentRoot ServerName и ServerAlias на нужные имена, а вместе с этим создаем директории DocumentRoot и кладем в них index.php с содержанием «working».
cd /etc/apache2/sites-available cat list.txt |awk '{print "cp site.sbm-bio.net "$1}'|bash cat list.txt |while read i; do \ echo "Обрабатываем: $i"; \ echo "sed -i 's/site.sbm-bio.net/$i/g; s/sbm-group.ru/$i/g' $i ; mkdir -p /var/www/$i/public_html ; echo working>/var/www/$i/public_html/index.php "|bash; \ done;
Приспичило вытащить навание всех полей для каждой таблицы в одной из баз MySQL.
Написал однострочную портянку, которая сделала всю работу.
Вот она:
root # echo "show tables;"| \ mysql -u root --password=HACKME dbname | \ grep -v Tables_in_ | \ while read i; \ do \ echo ====$i==== ; \ echo "describe \`$i\` ;" | \ mysql -u root --password=HACKME dbname ; \ echo "==================="; \ echo; echo; \ done | \ grep -v Field | awk '{print $1}'
Записывал конечно все это без переносов - в одну строку. Вот оригинал:
echo "show tables;"|mysql -u root --password=HACKME dbname | grep -v Tables_in_ | while read i; do echo ====$i==== ; echo "describe \`$i\` ;" |mysql -u root --password=HACKME dbname ; echo "==================="; echo; echo; done |grep -v Field |awk '{print $1}'
Встала задачка конвертировать видео-файлы в формат FLV. Тут лучшим инструментом является mencoder, поставляемый с mplayer. Компетентные люди сказали, что брать mplayer лучше всего из svn. Взял из trunc/ - собиралось конечно не без проблем - в моем любимом Debian пришлось поколдовать с установкой библиотек-dev. В общем собрал, но man mencoder читать было пока некогда - выкладываю тут строку, полученную от компетентных лиц :). Уже проверил - реально работает.
/usr/local/bin/mencoder Mov.wmv -o vvo.flv -of lavf \ -oac mp3lame -lameopts cbr:br=64 -af lavcresample=22050 \ -ovc vfw -xvfwopts codec=vp6vfw.dll \ -vf yadif,scale=640:480,flip \ -ss 000:00:15 -endpos 000:00:18
-ss и -endpos нужны только если вы собираетесь образать ролик - это соответственно смещение начала среза и его конца.
Если вы собираетесь пускать FLV потоком через nginx или php-скрипт - придется расставить ключевые кадры.
В этом поможет ruby-скрипт flvtool2
flvtool2 -UP rolik.flv
Все проверено - стриминг видео пашет!
Есть файл в котором в каждой строке должно быть 4 слова. Те строки где больше слов - нужно удалить!
Сначала неправильный вариант
cat 16.07.mail |awk '{if(NF>4){print "sed -i \"" NR " d\" 16.07.mail";}}'|bash
После первого прохода номера строк сдвигаются и в следующие проходы удаляются нужные строки.
Исправим ситуацию:
while true; do cat 16.07.mail |awk '{if(NF>4){print NR;}}'|head -n 1|awk '{print "echo " $1"; sed -i \"" $1 " d\" 16.07.mail"}'|bash ; done
Работает такая штука безумно долго, но зато надежно!
tail -n 300 access.log|grep "GET / "|awk '{a[$1]++;} END{for( i in a){ if(a[i]>5){ print i;}}}' | awk -F '.' '{print $1"."$2"."$3".0/24"}'|while read i; do iptables -I INPUT -s $i -j DROP; echo $i; done;
Подсчитаем кол-во коммитов каждого коммитера в некотором репозитории Subversion:
svn log -r 0:HEAD|grep line|awk -F '|' '{a[$2]++} END{for(i in a){print a[i]” “i;}}’|sort -nr
скрипт выдаст список в два столбца - в первом кол-во коммитов, а во втором логин участника. Список сортируется по количеству коммитов по убыванию.
Поменял название поля в БД - встала задача поменять поле везде где используется его имя. Используется оно у меня в конфигурационных файлах и в шаблонах. Задача усугубляется еще и тем что все дерево каталогов лежит под SVN - а файлы в каталогах .svn трогать нельзя. Чешем репу… Эксперементируем - вот что получается:
Изменяем шаблоны:
grep -rn 'sort' templates|grep -v svn|awk -F ':' '{print $1}'|sort|uniq|while read i; do sed -i 's/sort/sorting/g' $i ; done
Изменяем конфиги:
sed -i 's/\[sort\]/[sorting]/g; /\[sorting\]/ a name="Сортировка" ; ' *.ini
Конфиги - это обычный двух-уровневый ini-файл. Задача была изменить имена уровней sort на sorting , и еще добавить к каждому из них параметр name=«Сортировка»
Эх…. и что бы я делал с такими задачами в винде???
Попросил меня друг написать скриптик, чтобы ресайзить все картинки из папки, перемещая при этом уменьшенные копии в другую папку.
Вот как это было:
find icons -exec file {} \;
icons: directory
icons/font_2.png: PNG image data, 128 x 128, 8-bit/color RGBA, non-interlaced
icons/hdd_mount1.png: PNG image data, 128 x 128, 8-bit/color RGBA, non-interlaced
icons/user_female.png: PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
icons/ascii.png: PNG image data, 128 x 128, 8-bit/color RGBA, non-interlaced
icons/kfloppy_1.png: PNG image data, 128 x 128, 8-bit/color RGBA, non-interlaced
icons/html.svgz: gzip compressed data, from Unix
icons/folder_yellow.svgz: gzip compressed data, from NTFS filesystem (NT)
icons/kfloppy_2.png: PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
icons/amor.png: PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
icons/font_bitmap.svgz: gzip compressed data, from Unix
будем уменьшать на 24 сначала отыскать все файлы. читать их в переменную
max@maximus:~/tmp$ find icons/ -type f |while read i; do echo $i; done icons/font_2.png icons/hdd_mount1.png icons/user_female.png icons/ascii.png icons/kfloppy_1.png icons/kfloppy_2.png icons/amor.png icons/mime_empty.avcs.png icons/image_3.png icons/colorscm_1.png icons/hd2-black.png icons/folder_cyan.png icons/image_4.png icons/folder_html111.png icons/source_h111.png icons/kchart_1.png max@maximus:~/tmp$
чтобы копировать нам поможет вот что:
max@maximus:~/tmp$ basename t/e/w/r.sl r.sl
Далее мы хотим ресайзить картинки
max@maximus:~/tmp$ convert --help |grep resize -resize geometry resize the image -support factor resize support: > 1.0 is blurry, < 1.0 is sharp max@maximus:~/tmp$
вставляем это в скрипт
max@maximus:~/tmp$ find icons/ -type f |while read i; do echo convert -resize 24X24 $i final/`basename $i`; done convert -resize 24X24 icons/font_2.png final/font_2.png convert -resize 24X24 icons/hdd_mount1.png final/hdd_mount1.png convert -resize 24X24 icons/user_female.png final/user_female.png convert -resize 24X24 icons/ascii.png final/ascii.png convert -resize 24X24 icons/kfloppy_1.png final/kfloppy_1.png convert -resize 24X24 icons/kfloppy_2.png final/kfloppy_2.png convert -resize 24X24 icons/amor.png final/amor.png convert -resize 24X24 icons/mime_empty.avcs.png final/mime_empty.avcs.png convert -resize 24X24 icons/image_3.png final/image_3.png convert -resize 24X24 icons/colorscm_1.png final/colorscm_1.png convert -resize 24X24 icons/hd2-black.png final/hd2-black.png convert -resize 24X24 icons/folder_cyan.png final/folder_cyan.png convert -resize 24X24 icons/image_4.png final/image_4.png convert -resize 24X24 icons/folder_html111.png final/folder_html111.png convert -resize 24X24 icons/source_h111.png final/source_h111.png convert -resize 24X24 icons/kchart_1.png final/kchart_1.png max@maximus:~/tmp$
Остается передать вывод обратно на исполнение
find icons/ -type f |while read i; do echo convert -resize 24X24 $i final/`basename $i`; done |bash
Проверим что получилось
$ find final/ -type f -exec file {} \;
final/font_2.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/hdd_mount1.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/user_female.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/ascii.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/kfloppy_1.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/kfloppy_2.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/amor.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/mime_empty.avcs.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/image_3.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/colorscm_1.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/hd2-black.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/folder_cyan.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/image_4.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/folder_html111.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/source_h111.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
final/kchart_1.png: PNG image data, 24 x 24, 8-bit/color RGBA, non-interlaced
можно конечно все делать в find через -exec или -xargs, но я обычно пишу однострочный скрипт потому что… 1) легче отлаживать . 2) до сих пор не знаю как ДВАЖДЫ подставить имя найденого файла в -exec
Нужно было вынуть из журнала вебсервера все урлы начинающиеся с больших букв.
Как всегда я написал однострочный скриптик:
cat access.log | \ grep --colour=auto 'GET /[A-Z0-9][A-Z0-9][A-Z0-9]*'|\ gawk '{ key = gensub(/^.*(\/[A-Z0-9][A-Z0-9]+).*$/,"\\1","g",$0); a[key]++; } END{ for(i in a){print a[i]"\t"i;}}'|\ sort -nr