Кен Томпсон и Деннис Ритчи
Unix. Легендарная операционная система оказала огромное влияние на
разработку программного обеспечения и всю информатику в целом. Из
неё выросли целые семейства Unix-подобных ОС, которыми все мы
пользуемся.
Язык программирования Си, Ричард Столлман и GNU, движение Open
Source, Линус Торвальдс с ядром Linux, маки, айфоны и Android.
Почти всё в системном программировании 21века
можно отследить до истоков до Unix.
Unix это фундаментальная база. Но что же в ней такого особенного?
Есть один секрет. Точнее, два.
Философия Unix
Есть две причины, почему Unix имела такой успех, распространившись
по всему миру. Во-первых, она написана на высокоуровневом языке Си,
что обеспечивало и переносимость возможность установки на любых
компьютерах, и адаптирование системы для разнообразных
специфических требований. Прежде операционные системы писали на
ассемблере конкретного компьютера.
Во-вторых это была
правильная операционная система.
Сделанная в соответствии с некими общими принципами, в соответствии
с цельной
философией Unix.
Брайан Керниган и Роб Пайк в книге
Unix. Программное окружение формулируют основную идею этой
философии:
Эффективность UNIX определяется применением особого
подхода к программированию, философией использования компьютера.
Для того, чтобы описать эту философию, одного предложения, конечно
же, недостаточно, но вот её основная идея мощность системы в
огромной степени определяется взаимодействием программ, а не их
наличием.
Многие Unix-программы по отдельности выполняют довольно тривиальные
задачи, но будучи объединёнными с другими, образуют полный и
полезный инструментарий.
Другими словами, философия Unix это
взаимодействие программ.
Как
говорил в
своей презентации Брайан Керниган, программы Unix словно
строительные блоки, которые можно комбинировать, складывая в
эффективные конструкции. Выход одной программы является входом
другой программы. Своеобразный конвейер (пайп).
Команды сочетаются в конвейер не только стандартными, очевидными
способами. Бывают и весьма нетривиальные сочетания.
Волшебные конвейеры
Проще всего понять эту магию на
конкретных
примерах. пусть этот будет хит-парад авторов из репозитория по
количеству коммитов, загрузка мемов с Reddit и смена обоев для
рабочего стола каждый час согласно оценкам в подреддите
/r/earthporn.
Список лидеров по числу коммитов
Начнём с простого примера: отобразить список авторов репозитория
git, отсортированных по количеству коммитов. Если представить
задачу в терминах конвейеров, то она довольно простая. Выводим логи
коммитов командой
git log
. Опция
--format=<format>
позволяет указать, в каком
формате отображать коммиты. В нашем случае
--format='%an'
выводит только имена авторов для
каждого коммита.
$ git log --format='%an'AliceBobDeniseDeniseCandiceDeniseAliceAliceAlice
Теперь утилита
sort
сортирует их по алфавиту.
$ git log --format='%an' | sortAliceAliceAliceAliceBobCandiceDeniseDeniseDenise
Далее используем
uniq
.
$ git log --format='%an' | sort | uniq -c 4 Alice 1 Bob 1 Candice 3 Denise
Согласно man-странице
uniq
, она учитывает только
соседние совпадающие строки. Вот почему нужно было сначала
отсортировать список. Флаг
-c
выводит перед каждой
строкой количество вхождений.
Как видим, выдача по-прежнему отсортирована по алфавиту. Осталось
только изменить способ сортировки по числовым значениям. Для этого
есть флаг
-n
.
$ git log --format='%an' | sort | uniq -c | sort -nr 4 Alice 3 Denise 1 Candice 1 Bob
Флаг
-r
указывает на обратный порядок сортировки. Вот
и всё. Теперь у нас есть список авторов, отсортированных по
количеству коммитов.
Вы знали, что можно добавить .json к любому URL на Reddit, чтобы
получить выдачу в формате JSON вместо обычного HTML? Это открывает
целый мир возможностей! Например, просмотр мемов прямо из командной
строки (ну, не совсем, потому что фактическое изображение будет
отображаться в графической программе). Мы можем просто запросить
файл напрямую через curl или wget:
https://reddit.com/r/memes.json
.
$ wget -O - -q 'https://reddit.com/r/memes.json''{"kind": "Listing", "data": {"modhash": "xyloiccqgm649f320569f4efb427cdcbd89e68aeceeda8fe1a", "dist": 27, "children":[{"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "memes","selftext": "More info available at....'......
Wget принимает опцию
-O
с указанием файла для записи.
Большинство программ, которые принимают такую опцию, также
допускают значение
-
, что означает стандартный вывод
stdout
(или ввод, в зависимости от контекста). Опция
-q
просто означает работу в тихом режиме, не отображая
информацию типа статуса скачивания. Теперь у нас есть большая
структура JSON. Чтобы проанализировать и осмысленно использовать
эти данные в командной строке, можно взять утилиту
jq
,
аналог sed/awk для JSON. У неё простой интуитивно понятный
язык.
Ответ JSON выглядит примерно так:
{ "kind": "Listing", "data": { "modhash": "awe40m26lde06517c260e2071117e208f8c9b5b29e1da12bf7", "dist": 27, "children": [], "after": "t3_gi892x", "before": null }}
Итак, здесь у нас тип
Listing
и массив
children
. Каждый элемент этого массива отдельный
пост.
Вот как выглядит один из элементов массива:
{ "kind": "t3", "data": { "subreddit": "memes", "selftext": "", "created": 1589309289, "author_fullname": "t2_4amm4a5w", "gilded": 0, "title": "Its hard to argue with his assessment", "subreddit_name_prefixed": "r/memes", "downs": 0, "hide_score": false, "name": "t3_gi8wkj", "quarantine": false, "permalink": "/r/memes/comments/gi8wkj/its_hard_to_argue_with_his_assessment/", "url": "https://i.redd.it/6vi05eobdby41.jpg", "upvote_ratio": 0.93, "subreddit_type": "public", "ups": 11367, "total_awards_received": 0, "score": 11367, "author_premium": false, "thumbnail": "https://b.thumbs.redditmedia.com/QZt8_SBJDdKLVnXK8P4Wr_02ALEhGoGFEeNhpsyIfvw.jpg", "gildings": {}, "post_hint": "image", ".................." "много строк скипнуто" ".................." }}
Здесь много интересных атрибутов, в том числе URL картинки с
мемом.
Мы можем легко получить список всех URL со всех постов:
$ wget -O - -q reddit.com/r/memes.json | jq '.data.children[] |.data.url'"https://www.reddit.com/r/memes/comments/g9w9bv/join_the_unofficial_redditmc_minecraft_server_at/""https://www.reddit.com/r/memes/comments/ggsomm/10_million_subscriber_event/""https://i.imgur.com/KpwIuSO.png""https://i.redd.it/ey1f7ksrtay41.jpg""https://i.redd.it/is3cckgbeby41.png""https://i.redd.it/4pfwbtqsaby41.jpg"......
Игнорируйте первые две ссылки, это в основном закреплённые посты от
модераторов.
Утилита
jq
считывает данные из стандартного входа и
получает JSON, который мы видели ранее. Затем указан массив постов
.data.children
. Синтаксис
.data.children[] |
.data.url
означает: пройти по каждому элементу массива и
вывести поле
url
, которое находится в поле
data
каждого элемента.
Таким образом, мы получаем список URL всех топовых мемов в
подреддите /r/memes на данный момент. Если хотите посмотреть лучшие
посты недели, нужно писать
https://reddit.com/r/memes/top.json?t=week
. Топ всех
времён:
t=all
, за год:
t=year
и так
далее.
Как только у нас есть список всех URL, можно просто передать его в
xargs. Это действительно полезная утилита для построения командных
строк из стандартного ввода. Из описания:
Команда xargs объединяет зафиксированный набор заданных
в командной строке начальных аргументов с аргументами, прочитанными
со стандартного ввода, и выполняет указанную команду один или
несколько раз.
Пустые строки игнорируются.
То есть такая команда:
$ echo "https://i.redd.it/4pfwbtqsaby41.jpg" | xargs wget -O meme.jpg -q
будет равнозначна этой:
$ wget -O meme.jpg -q "https://i.redd.it/4pfwbtqsaby41.jpg"
Теперь можно просто передать список URL'ов в просмотрщик
изображений
feh
или
eog
,
который принимает URL в качестве допустимого аргумента.
$ wget -O - -q reddit.com/r/memes.json | jq '.data.children[] |.data.url' | xargs feh
И у нас запускается feh с мемами, которые можно листать клавишами
со стрелками, словно это картинки на локальном диске.
Или можно загрузить все изображения с помощью wget, заменив
feh
на
wget
в строке выше.
А возможности безграничны. Ещё один вариант использования картинок
с Reddit через JSON установка топовой картинки подреддита
/r/earthporn в качестве
обоев рабочего стола:
$ wget -O - -q reddit.com/r/earthporn.json | jq '.data.children[] |.data.url' | head -1 | xargs feh --bg-fill
Если хотите, можно настроить cron-задание, которое выполняется
каждый час.
Лес в Нидерландах [20001333]
Гренландия [40323024]
Конечно, вместо /r/earthporn можно брать картинки из других
подреддитов.
Вот в чём мощь конвейеров Unix. Одна-единственная строка делает
всё: скачивает файл JSON, разбирает его, находит нужные данные,
потом скачивает картинку по URL и устанавливает её в качестве
обоев.
Это всего несколько случайных примеров. В реальности можно очень
многое сделать однострочной командой в консоли, построив конвейер
из простых утилит.
Работа, которая доставляет удовольствие
Особая философия Unix настолько глубока и фундаментальна, что
породила целые классы Unix-подобных систем, к числу которых
относятся BSD, macOS и Linux. Все они построены на этой философии.
А побочный эффект работы в такой системе чувство
правильности и цельности. Что так всё и должно работать: из
кирпичиков, маленьких строительных блоков, которые сцепливаются в
конвейеры любой сложности. Это же гениально.
Интересные факты об отцах-основателях
Может, через много лет Томпсона и Ритчи канонизируют, причислив к
лику отцов-основателей разумного компьютерного мира. А сейчас
цифровые археологи продолжают откапывать всё новые факты из истории
Unix.
Например, в 2014 году исследователь Лея Нойкирхер
нашла в
дампах исходного дерева BSD 3 файл
/etc/passwd с паролями всех ветеранов, таких как Деннис Ричи,
Кен Томпсон, Брайан В. Керниган, Стив Борн и Билл Джой.
Для хэшей использовался алгоритм
crypt(3) с максимальной длиной пароля 8 символов. Лея взломала
их стандартными брутерами
john и
hashcat.
Большинство паролей были очень слабыми. Только пароль Кена Томпсона
не поддавался взлому. Даже полный перебор всех строчных букв и цифр
(несколько дней) не дал результата. Неужели он использовал
специальные символы? Лишь в 2017 году Найджел Уильямс в списке
рассылки
The
Unix Heritage Society раскрыл эту тайну. Пароль со всеми
возможными символами оказался
q2-q4!
: это первый ход
пешкой на две клетки в
описательной нотации и начало
многих типичных дебютов, что очень хорошо вписывается в
бэкграунд Кена Томпсона по компьютерным шахматам. Брутфорс на
видеокарте AMD Radeon Vega64 занял более четырёх дней.
Некоторые из разработчиков Unix живы и здравствуют. Если хотите
посмотреть, какие операционные системы и программы они используют
на своих домашних компьютерах вот
галерея 2002 года и
2015 года. Каждого в электронном письме попросили сделать
скриншот текущего десктопа сразу, как только они прочитают эти
слова.
Десктоп Брайана Кернигана (октябрь 2015)
Деннис Ритчи (19412011) в 2002 году использовал необычную
установку: его домашний клиент на NT4 подключён по ISDN к
удалённому серверу Plan9 в центральном офисе Bell Labs.
Plan9
инновационная ОС, основанная на концепции распределённых
вычислений. Любая машина может использовать любые ресурсы с любой
другой машины как собственные. Сейчас эту концепцию пытаются
реализовать в виде контейнеров, VM и микросервисов, а там она
реализована на уровне ядра ОС.
Дальше у нас
Брам Моленар, автор многофункционального текстового редактора
Vim:
Десктоп Брама Моленара (сентябрь 2002)
Десктоп Брама Моленара (ноябрь 2015)
Джордан Хаббард, один из сооснователей проекта FreeBSD:
Десктоп Джордана Хаббарда (ноябрь 2015)
P. S. К сожалению, Линус Торвальдс не смог сделать скриншот из
своей консоли в текстовом режиме.
Будем надеяться, новое поколение современных разработчиков не
забудет, что мы стоим на плечах гигантов.
На правах рекламы
Устанавливайте любые операционные системы на наших
VDS с мгновенной активацией. Сервер готов к работе через минуту
после оплаты!