среда, 4 августа 2010 г.

Преобразовать имена файлов к нижнему регистру

Перевод статьи: Convert Filenames to Lowercase

25 июля 2008, Фил Хьюз (Phil Hughes)

Я собирался сказать, что я написал это вчера, но отметка времени файла указывает на то, что это было 22 ноября 1998. Ничего нового, ничего особенного, это просто работает.

Вернёмся в старое-доброе время операционных систем, не понимавших разницы между NAME и name. В результате, если иногда приходится копировать файлы с гибких дисков (помните такие?), созданных на Давно Онемевшей Системе, можно получить свалку каталогов с именами файлов в верхнем регистре. Поскольку мы, опытные старожилы UNIX, пользуемся хитрой уловкой для вывода имён каталогов до имён файлов файлов по команде ls (а именно - начинаем имена каталогов с букв в верхнем регистре), наличие имён файлов с символами в верхнем регистре нас раздражает.

Поскольку я слишком часто пользовался командой mv и ввод команд типа mv FILE.TXT file.txt меня окончательно изнурил, я написал этот сценарий. Я думал, что я просто сделал косметический ремонт, но на самом деле сценарий делает работу и в нём легко разобраться. (Номера строк приведены просто для того, чтобы на них ссылаться.)
1   #!/bin/sh
 2   # lowerit
 3   # преобразовывает имена всех файлов в текущем каталоге к нижнему регистру
 4   # работает только над обычными файлами -- не меняет имена каталогов
 5   # запрашивает подтверждение перед заменой существующего файла
 6   for x in `ls`
 7   do
 8     if [ ! -f $x ]; then
 9       continue
10     fi
11     lc=`echo $x | tr '[A-Z]' '[a-z]'`
12     if [ $lc != $x ]; then
13       mv -i $x $lc
14     fi
15   done
Строка 6 начинает цикл (который заканчивается в строке 15). Команда ls возвращает список имён файлов, которые последовательно назначаются переменной оболочки x. if test (строки с 8 по 10) проверяет, является ли имя текущего файла именем простого файла. Если нет, остаток выражения в текущего прохода цикла пропускается.

Если выполняется строка 11, то известно, что обрабатывается обычный файл. С помощью tr мы приводим имя файла в нижний регистр и присваиваем новое имя переменной оболочки lc. Затем в строке 12 происходит проверка, что имя файла в нижнем регистре отличается от исходного. Если это так, то выполняется 13 строка, которая меняет исходное имя файла на новое имя в нижнем регистре. Опция -i заставляет mv спрашивать подтверждение, если команда собирается перезаписать существующий файл.

Фил Хьюз (Phil Hughes)

Дополнение переводчика от 13-05-2012. Нашёл ещё один вариант скрипта для этой задачи:
$ find ./ -type f | awk '{ print $1 " " tolower($1) }' | xargs -L 1 mv

Проверка правильности IP-адресов из сценария Bash

Перевод статьи: Validating an IP Address in a Bash Script

26 июня 2008, Митч Фрэзер (Mitch Frazier)

Я часто пишу об использовании массивов bash и о регулярных выражениях bash, поэтому решил привести более полезный пример их использования для проверки правильности IP-адресов.

Задача очевидна: IP-адреса являются 32-битными значениями, записанными как четыре числа (отдельные байты IP-адреса), разделённых точками. Каждое из четырёх чисел может принимать значение в диапазоне от 0 до 255.

Следующий сценарий bash содержит функцию, которая возвращает истину, если её передан правильный IP-адрес и ложь в противном случае. В bash под истиной понимают завершение с нулевым кодом, всё остальное означает ложь. Код команды/функции bash помещается в переменную "$?".
#!/bin/bash

# Проверка правильности IP-адреса:
# Способ применения:
#      valid_ip IP_АДРЕС
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   ИЛИ
#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi
#
function valid_ip()
{
  local ip=$1
  local stat=1

  if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
      && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
  fi
  return $stat
}

# При непосредственном запуске выполним несколько проверок.
if [[ "$(basename $0 .sh)" == 'valid_ip' ]]; then
  ips='
4.2.2.2
a.b.c.d
192.168.1.1
0.0.0.0
255.255.255.255
255.255.255.256
192.168.0.1
192.168.0
1234.123.123.123
'
  for ip in $ips
  do
    if valid_ip $ip; then
      stat='good';
    else
      stat='bad';
    fi
    printf "%-20s: %s\n" "$ip" "$stat"
  done
fi
Если сохранить этот сценарий под именем "valid_ip.sh" и запустить его напрямую, он проведёт несколько проверок и выведет результаты:
# sh valid_ip.sh
4.2.2.2             : good
a.b.c.d             : bad
192.168.1.1         : good
0.0.0.0             : good
255.255.255.255     : good
255.255.255.256     : bad
192.168.0.1         : good
192.168.0           : bad
1234.123.123.123    : bad
В функции valid_ip, чтобы удостовериться в том, что рассматриваемый IP-адрес состоит из четырёх разделённых точками чисел, используется регулярное выражение в операторе if:
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
Если проверка пройдена, код внутри оператора if разделяет рассматриваемый IP-адрес на четыре части по точкам и помещает части в массив:
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
Эти действия меняют переменную bash, которая называется "внутренний разделитель полей" (Internal Field Separator). Обычно она используется для обработки слов, разделённых пробелами, по после этого bash будет использовать для разделения полей точки. Поместим значение рассматриваемого IP-адреса внутрь скобок и присвоим их значение массиву, поместив каждое из полей, разделённых точками, в отдельную ячейку массива. Теперь проверим отдельные поля, чтобы удостовериться в том, что они меньше или равны 255. Результат проверки сохраним, так чтобы его можно было вернуть в качестве значения функции:
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
  && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
Отметим, что не обязательно проводить проверку равно ли число нулю или оно больше нуля, так как проверка регулярным выражением уже отфильтровала всё, что не состоит из точек и цифр.


Митч Фрэзер (Mitch Frazier) является помощником редактора в Linux Journal и веб-редактором в linuxjournal.com.

воскресенье, 25 июля 2010 г.

Quake2 на Debian GNU/Linux

Ранее я уже писал про то, как можно запустить Quake в Linux:
  1. Quake в Linux
  2. Запуск Quake на движке Nexuiz
Запуск Quake 3 тоже не представляет проблем, если воспользоваться для этого игрой OpenArena.

Вот чего мне до сих пор не удавалось, так это приличным образом запустить в Debian любимый мной Quake 2, который во времена студенчества мы с тремя моими друзьями перевели на русский язык. Но теперь я нашёл готовые deb-пекеты для установки Quake 2 в Debian: Yamagi Quake II Client

Для установки Quake 2 скачиваем три пакета вот отсюда Debian packages of Yamagi Quake II:
$ wget http://deponie.yamagi.org/quake2/debs/i386/yamagi-quake2_2.11-1_i386.deb
$ wget http://deponie.yamagi.org/quake2/debs/all/quake2-data_16_all.deb
$ wget http://deponie.yamagi.org/quake2/debs/i386/yamagi-quake2-addons_1.1_i386.deb
И незамедлительно устанавливаем их:
# dpkg -i yamagi-quake2_2.11-1_i386.deb
# dpkg -i quake2-data_16_all.deb
# dpkg -i yamagi-quake2-addons_1.1_i386.deb
Теперь достаём с полки диск с Quake 2 и копируем содержимое каталога baseq2 в каталог /usr/share/games/quake2/baseq2. Достаточно скопировать только файл pak0.pak:
# cp /cdrom/BASEQ2/PAK0.PAK /usr/share/games/quake2/baseq2/pak0.pak
И запускаем:
$ yamagiq2
Как всегда, без ложки дёгтя в бочке мёда не обходится.

Во-первых, для работы quake2 необходимо наличие в системе пакетов libogg0 (>= 1.1.3), libsdl1.2debian (>= 1.2.10-1), libvorbis0a (>= 1.1.2), libvorbisfile3 (>= 1.1.2), zlib1g (>= 1:1.2.1). Проверяем наличие нужных пакетов и устанавливаем недостающие.

Во-вторых, звук в игре по непонятной мне причине немного заикается и хрипит. Как я ни пытался улучшить звук, ничего особого не получилось. С помощью следующей команды:
$ yamagiq2 +s_khz 44 +s_loadas8bit 0 +snd_restart
Удалось лишь немного улучшить качество звука в те моменты, когда он не заикается и не хрипит. Но заикаться и хрипеть от этого он всё равно не перестал.

И ещё - для запуска игры необходимо наличие видеокарты, поддерживающей аппаратное ускорение OpenGL. Поддержка программной отрисовки из этого пакета была нещадно выпилена.

Из приятного можно отметить следующее:
  • Можно играть не только в классический Quake 2, но и в его моды Reckoning от Xatrix и Ground Zero от Rogue.
  • Можно слушать музыку с компакт-диска без компакт-диска, благо в состав пакета входит скрипт, который может снять треки с диска, закодировать их в OGG/Vorbis и положить на жёсткий диск, откуда и можно в дальнейшем воспроизводить треки.
Для добавления модов скопируем каталоги с модами в соответствующее место, откуда их может взять движок игры.
# cp -R /home/stupin/quake2/Quake2Mods/RecKoning/xatrix /usr/share/games/quake2/
# cp -R /home/stupin/quake2/Quake2Mods/GroundZero/rogue /usr/share/games/quake2/
Теперь для запуска одного из модов можно воспользоваться следующими командами:
$ yamagiq2 +s_khz 44 +s_loadas8bit 0 +snd_restart +set game xatrix
$ yamagiq2 +s_khz 44 +s_loadas8bit 0 +snd_restart +set game rogue
Для съёма треков с компакт-диска можно воспользоваться примером скрипта, находящимся в одном из пакетов с игрой: /usr/share/doc/yamagi-quake2/examples/cdripper.sh

Ну и напоследок, снимок на память: