Приступим?
$ sudo cat /var/log/messages | tail -n 40 | grep "sd" | grep "[Rr]emovable
Понятно, что из всего вывода будет отфильтрованы только строчки содержащие
"sd" и слова "removable" и "Removable".
Почему "строчки" а не "одна строка"?
Потому, что в 40 строк может вместиться два или три раза журналируемого
блока текста о подключаемом устройстве. И мы получим три раза одно и тоже.
Чтобы предотвратить такое поведение - подрежем полученный хвост:
>
$ sudo cat /var/log/messages | tail -n 40 | grep "sd" | grep "[Rr]emovable | tail -n 1
Получим на выходе искомую строку:
sd 2:0:0:0: [sda] Attached SCSI removable disk
Теперь избавимся от лишнего текста.
В этом нам поможет awk (gawk)
Самое простое, что можно придумать - это:
$ awk -F"]" '{print $1}'
"Разрезать" фразу разделителями "]" и распечатать первую подстроку.
Вот, и искомая команда:
$ sudo cat /var/log/messages | tail -n 40 | grep "sd" | grep "[Rr]emovable | tail -n 1 | awk -F"]" '{print $1}' | awk -F"[" '{print $2}'
На выходе получим:
sda
Теперь еще один фокус, ради которого все это размусоливаливалось.
Переменная есть, есть отфильтрованное ее значение. Как записать?
Для записи в переменную вывода сторонних программ используют обратные
кавычки - "`".
Наш скрипт теперь получает вторую строчку:
SDev=`sudo cat /var/log/messages | tail -n 40 | grep "sd" | grep "[Rr]emovable | tail -n 1 | awk -F"]" '{print $1}' | awk -F"[" '{print $2}'`
Проверить, что содержит переменная SDev просто.
Это делается командой echo..
Чтобы ты понял, как удобно работать в командной строке приведу еще один
трюк.
>
Команды могут выполняться последовательно и параллельно.
Чтобы выполнялись последовательно одна за другой - используй знак ";"
$ mkdir NewFolder; mkdir NewFolder/NewSubFolder; date > NewFolder/time;
Это же используется при построении многокомандного цикла или блока в одну строку.
Конструкция
if [ -x "/mnt/usb" ]; then echo Good; else echo Bad; fi
будет преобразована в:
$ if [ -x "/mnt/usb" ]; then echo Good; else echo Bad; fi
Чтобы "отпустить" выполнение процесса в свободное плавание и "освободить" вывод командной строки, достаточно добавить в конце команды знак "&"
$ play /home/lilo/sample.wav &
Теперь вернемся к нашим баранам: переменной и ее значении.
для теста вне скрипта все уже известно:
$ SDev=`sudo cat /var/log/messages | tail -n 40 | grep "sd" | grep "[Rr]emovable | tail -n 1 | awk -F"]" '{print $1}' | awk -F"[" '{print $2}'`; echo $SDev
Теперь поговорим о партициях.
Конечно, ты мог верно подметить, что в журнале появилась строка, где
сообщили, что псевдоустройство sda имеет дочернее под-устройство sda1
Так мы приходим к еще одной известной "проблеме".
Некоторые флеш-диски отформатированы с таблицей FAT, а некоторые
(например, устройства файловых систем мобильных телефонов) - нет!
Вот, у меня такая ситуация! С чем меня можно поздравить!
Флеш-диски видятся, как /dev/sda1, а при подключении телефона кабелем
DKU-2 в гнездо USB, система его определяет, как диск, но без таблицы ФАТ.
Просто /dev/sda
Забавно, правда?
Но и это не главное! В журнале может и не появиться такой замечательной
инормации от других флеш-дисков.
Информацию о том, на какое псевдоустройство будет завязан тот или иной
флеш-накопитель, мы будем получать всегда!
Чтобы избежать службы в армии, неразберихи, что монтировать
(/dev/sda или /dev/sda1), проанализируем псевдоустройство сами.
Команда fdisk поможет нам в этом.
$ sudo fdisk -l /dev/$SDev
На выходе получим:
Disk /dev/sda: 1050 MB, 1050146816 bytes 33 heads, 61 sectors/track, 254 cylinders Units = cylinders of 2013 * 2048 = 4122624 bytes Device Boot Start End Blocks Id System /dev/sda1 1 254 1022482 b W95 FAT32
Вот, тебе и диск...
Отфильтруем:
$ sudo fdisk -l /dev/$SDev | grep "/dev/" | grep -v "Disk"
Получим:
/dev/sda1 1 254 1022482 b W95 FAT32
Подгоним по ширине напильником, awk...
По-умолчанию, awk в роли разделителя берет пробел.
$ sudo fdisk -l /dev/$SDev | grep "/dev/" | grep -v "Disk" | awk '{print $1}'
Запишем в переменную.
Это будет нашей третьей строчкой скрипта.
VerifyDev=`sudo fdisk -l /dev/$SDev | grep "sd" | grep -v "Disk" | awk '{print $1}'`;
А, вот, если подключу телефон, то переменной VerifyDev ничего не присвоится. Так, как партиций у псевдоустройства не будет.
Это мы тоже обработаем.
Конструкция if будет такой:
if [ -n "$VerifyDev" ]; then echo Good; ... else echo Bad; ... if
Распознавать, есть ли у устройства таблица ФАТ или нет, мы научились и научились обрабатывать это.
Во время монтирования, утилита mount считывает сначала данные об устройстве в /etc/fstab, если оно там описано, а затем дополняет назначениями от пользователя.
Я бы хотел, чтобы любой флеш-носитель монтировался в одну директорию
/mnt/usb.
Если указывать это в /etc/fstab, то получим конфликт двух строк.
Строки о /dev/sda и о /dev/sda1
Предлагаю скопировать /etc/fstab в /etc/fstab.orig
Затем "анализировать" журнал. Исходя из полученных данных,
дописывать /etc/fstab необходимой строчкой и в конце - монтировать.
Вот, как это сделал я.
Думаю, дальше мусолить - бесполезно...
cp --reply=yes /etc/fstab.orig /tmp/fstab.new; if [ -n "$VerifyDev" ]; then echo "$VerifyDev /mnt/usb auto noauto,owner,kudzu,ro 0 0">>/tmp/fstab.new; else echo "/dev/$SDev /mnt/usb auto noauto,owner,kudzu,ro 0 0">>/tmp/fstab.new; fi sudo cp --reply=yes /tmp/fstab.new /etc/fstab rm -rf /tmp/fstab.new sudo mount -o iocharset=utf8 /mnt/usb
Я еще раз повторюсь. Пишу, не для изобретения велосипеда.
Есть демон automount, который за все это отвечает.
Но, как устроено - всегда узнать интересно. И попрактиковаться.
К тому же, как сравнить, какой из способов эффективнее?