Статья состоит из двух частей: развлекательной - краткой истории Unix и изложения основ философии Unix, и практической. Практические примеры далеки от идеала, и призваны показать направление решения, а не предоставить готовый 100% ответ. В целом статья носит обзорный характер и не претендует на полноту освещения затронутых вопросов, что, впрочем, должно позволить не уснуть читателю до последнего абзаца. И так...
История UNIX
..все началось в 1969 году, когда в недрах компании AT&T. Силами ее подразделения Bell Labs была разработана первая UNIX система. Во главе сотрудников исследовательской группы Bell стояли Кен Томпсон (Ken Tompson) и Деннис Ритчи (Dennis Ritchie).Интересны факт, первое название системы было UNICS (UNiplexed Information and Computing Service). Этот вариант был предложен сотрудником компании AT&T Брайаном Керниганом, и, уже несколько позднее, система обрела свое знаменитое и судьбоносное название UNIX.
Одним из важнейших результатов разработки UNIX можно смело назвать рождение бессмертного языка C. Дело в том, что первые версии системы писались на ассемблере, что, вместе с высокой производительностью, вносило некоторые ограничения в переносимость системы. Решение Томпсона переписать все на языке высоко уровня и привело к появлению нового языка, прародителем которого был язык BCPL. Теперь, для портирования системы на новую архитектуру, достаточно было написать для нее компилятор языка C.
Еще одним ключевым результатом разработки UNIX стали конвейеры. Конвейеры - это цепочка программ, каждая из которых выполняет некоторое действие и передает результат на вход следующей в конвейере программе. Таким образом, программы, выстраиваясь в цепочку, приводят к результату, который ограничен только воображением пользователя. Именно конвейеры стали ключевым изобретением в UNIX, породившим понятие Unix way.
Философия UNIX
Идея философии заключается в написании небольших программ, решающих только одну определенную задачу и взаимодействующих между собой с помощью текстовых потоков.Изобретатель каналов UNIX Дуг МакИлрой, обобщил философию пути UNIX следующим образом:
- «Философия UNIX гласит:
- Пишите программы, которые делают что-то одно и делают это хорошо.
- Пишите программы, которые бы работали вместе.
- Пишите программы, которые бы поддерживали текстовые потоки, поскольку это универсальный интерфейс».
- Красиво — небольшое.
- Пусть каждая программа делает что-то одно, но хорошо.
- Собирайте прототип как можно раньше.
- Предпочитайте переносимость эффективности.
- Храните данные в простых текстовых файлах.
- Используйте возможности программ для достижения цели.
- Используйте сценарии командной строки для улучшения функционала и переносимости.
- Избегайте пользовательских интерфейсов, ограничивающих возможности пользователя по взаимодействию с системой.
- Делайте каждую программу «фильтром».
- Позвольте пользователю настраивать окружение.
- Делайте ядра операционной системы маленькими и легковесными.
- Используйте нижний регистр и придерживайтесь кратких названий.
- Не храните тексты программ в виде распечаток («Спасите деревья!»).
- Не сообщайте пользователю об очевидном («Молчание — золото»).
- Разбивайте сложные задачи на несколько простых, выполняемых параллельно («Мыслите "параллельно"»).
- Объединённые части целого есть нечто большее, чем просто их сумма.
- Ищите 90-процентное решение.
- Если можно не добавлять новый функционал, не добавляйте его («Чем хуже, тем лучше»).
- Мыслите иерархически.
и снова спасибо вики за информацию
Потоки ввода/вывода и каналы.
Не смотря на огромное количество красивых заявлений в принципах философии UNIX, наиболее распространенное представление о UNIX way строится вокруг конвейеров.Основой конвейеров программ в UNIX являются потоки ввода/вывода. Потоки ввода/вывода - это абстракции, позволяющие производить чтение и запись информации единым образом вне зависимости от того, что является ее источником (или приемником). Источником информации для потоков может быть файл, программа или устройство.
В операционных системах существует минимум три стандартных потока:
- поток ввода(в него помещается информация вводимая с клавиатуры),
- поток вывода(из него читается информация выводимая на экран)
- поток ошибок(предназначенный для вывода отладочной информации и информации об ошибках)
команда < файл
Изменяет поток ввода, использует указанный файл как источник данных для стандартного потока ввода.
команда > файл
Направляет стандартный поток вывода в файл. Если файл не существует, он будет создан; если существует — перезаписан сверху.
команда >> файл
Направляет стандартный поток вывода в файл. Аналогично предыдущей команде, создает файл в случае его отсутствия, но если файл существует, не затирает его, а дописывает новую информацию в конец файла.
Чтобы понять, зачем такие сложности, приведу бытовой пример. Вы, как уважающий себя любитель музыки, скачали любимый музыкальный альбом в формате .flac к которому прилагается файл .cue с описанием треков альбома. Но автор раздачи при создании .cue файла использовал кодировку, отличающуюся от вашей(пользователям линукс такое точно знакомо) и теперь плеер, вместо внятной информации о треке, показывает крякозябры. Чтобы изменить кодировку файла, можно воспользоваться утилитой iconv:
$ iconv -f cp1251 -t utf8 < album_cp1251.cue > album_utf8.cue
Потоки можно перенаправлять не только в файл, но и в программы. Для этого существует команда | . Ее вызов эквивалентен следующей последовательности команд:
команда_1 > temp.txt команда_2 < temp.txt rm temp.txt
Чтобы показать всю мощь и гибкость каналов, вернемся к "музыкальному" примеру. Как правило, вместе с .cue файлом идет большой файл .flac, содержащий в себе весь альбом описываемый .cue файлом. На сегодня далеко не все музыкальные плееры способны понимать, исходя из информации в .cue, что во .flac несколько треков. Это приносит серьезные неудобства. Как вариант решения проблемы, можно единый .flac разбить на кучу маленьких, содержащих ровно по одному треку, файлов. Для этого можно воспользоваться следующими утилитами:
- cuebreakpoints - выводит время окончания треков из CUE или TOC файлов.
- shnsplit - разбивает .flac файл на несколько маленьких в соответствии с временными отметками, поданными на вход программы.
- cuetag - записывает теги на основе информации в .cue файле
$ cuebreakpoints "Pink Floyd - Animals.cue" | shnsplit -o flac "Pink Floyd - Animals.flac"
По умолчанию, имена файлов генерируются как split-track<номер>.flac. Чтобы изменить часть имени перед номером, существует ключ -n. Подробнее о нем в man странице.Чтобы добавить в получившиеся файлы описание тегов, надо вызвать cuetag:
$ cuetag "Pink Floyd - Animals.cue" split-track*.flac
Главное, не забыть изменить кодировку .cue файла перед присваиванием тегов ;)Вообще, проблема кодировки тегов присуща не только .flac файлам. Любители музыки в mp3 наверняка это хорошо знают. Следующий конвейер команд находит все Mp3 файлы в указанной директории и меняет кодировку их тегов, а также удаляет устаревшие теги:
$ find /home/music -iname "*.mp3" -print0 | xargs -0 mid3iconv -e CP1251 --remove-v1
И так, мы подошли к инструменту, который делает подход unix не просто интересным и местами удобным, а по настоящему мощным инструментом в решении повседневных задач. Я говорю о скриптах - последовательности команд, записанных в файл и выполняемых как одна единая команда.
Для примера воплотим в жизнь идею, о совершенствовании решения по исправлению mp3 тегов. Для это необходимо создать текстовый файл и записать в него следующее содержимое:
#!/bin/sh
if [ $# == 0 ]; then
echo "Не указана директория"
exit -1
fi
find $1 -iname "*.mp3" -print0 | xargs -0 mid3iconv -e CP1251 --remove-v1
Чтобы сделать файл исполняемым, выполните
$ chmod +x <файл со скриптом>
Приведенный скрипт подставляет первый аргумент вызова в качестве директории в команду find. Обратите внимание на конструкции $# и $1. Первая - это переменная, возвращающая количество аргументов вызова скрипта, вторая переменная возвращает первый аргумент вызова. Скрипт проверяет количество аргументов и, если аргументы не были указаны, сообщает об этом и завершает свою работу. Скрипт далек от идеала и не решает многих нюансов с передачей директорий в качестве параметра, но аккуратно записанный полный путь вполне должен дать скрипту корректно отработать.
4 комментария:
Хорошо изложено, спасибо.
Приятно знать, что писал не зря.
Очень хорошо написано, благодаря этой статье многое стало ясным и понятным
Супер) Спасибо. UNIX рулит
Отправить комментарий