- PVSM.RU - https://www.pvsm.ru -
Кен Томпсон и Деннис Ритчи
Unix. Легендарная операционная система оказала огромное влияние на разработку программного обеспечения и всю информатику в целом. Из неё выросли целые семейства Unix-подобных ОС, которыми все мы пользуемся.
Язык программирования Си, Ричард Столлман и GNU, движение Open Source, Линус Торвальдс с ядром Linux, маки, айфоны и Android. Почти всё в системном программировании 21 века можно отследить до истоков — до Unix [1].
Unix — это фундаментальная база. Но что же в ней такого особенного? Есть один секрет. Точнее, два.
Есть две причины, почему Unix имела такой успех, распространившись по всему миру. Во-первых, она написана на высокоуровневом языке Си, что обеспечивало и переносимость — возможность установки на любых компьютерах, и адаптирование системы для разнообразных специфических требований. Прежде операционные системы писали на ассемблере конкретного компьютера.
Во-вторых — это была правильная операционная система. Сделанная в соответствии с некими общими принципами, в соответствии с цельной философией Unix [2].
Брайан Керниган и Роб Пайк в книге «Unix. Программное окружение» [3] формулируют основную идею этой философии:
Эффективность UNIX определяется применением особого подхода к программированию, философией использования компьютера. Для того, чтобы описать эту философию, одного предложения, конечно же, недостаточно, но вот её основная идея — мощность системы в огромной степени определяется взаимодействием программ, а не их наличием.
Многие Unix-программы по отдельности выполняют довольно тривиальные задачи, но будучи объединёнными с другими, образуют полный и полезный инструментарий.
Другими словами, философия Unix — это взаимодействие программ. Как говорил в своей презентации Брайан Керниган [4], программы Unix — словно строительные блоки, которые можно комбинировать, складывая в эффективные конструкции. Выход одной программы является входом другой программы. Своеобразный конвейер (пайп).
Команды сочетаются в конвейер не только стандартными, очевидными способами. Бывают и весьма нетривиальные сочетания.
Проще всего понять эту магию на конкретных примерах [5]. пусть этот будет хит-парад авторов из репозитория по количеству коммитов, загрузка мемов с Reddit и смена обоев для рабочего стола каждый час согласно оценкам в подреддите /r/earthporn [6].
Начнём с простого примера: отобразить список авторов репозитория git, отсортированных по количеству коммитов. Если представить задачу в терминах конвейеров, то она довольно простая. Выводим логи коммитов командой git log
. Опция --format=<format>
позволяет указать, в каком формате отображать коммиты. В нашем случае --format='%an'
выводит только имена авторов для каждого коммита.
$ git log --format='%an'
Alice
Bob
Denise
Denise
Candice
Denise
Alice
Alice
Alice
Теперь утилита sort
сортирует их по алфавиту.
$ git log --format='%an' | sort
Alice
Alice
Alice
Alice
Bob
Candice
Denise
Denise
Denise
Далее используем 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 [8]
.
$ 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
[9], аналог 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 [10]
или eog [11]
, который принимает 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-задание, которое выполняется каждый час.
[12]
Лес в Нидерландах [13] [2000×1333]
[14]
Гренландия [13] [4032×3024]
Конечно, вместо /r/earthporn можно брать картинки из других подреддитов.
Вот в чём мощь конвейеров Unix. Одна-единственная строка делает всё: скачивает файл JSON, разбирает его, находит нужные данные, потом скачивает картинку по URL и устанавливает её в качестве обоев.
Это всего несколько случайных примеров. В реальности можно очень многое сделать однострочной командой в консоли, построив конвейер из простых утилит.
Особая философия Unix настолько глубока и фундаментальна, что породила целые классы Unix-подобных систем, к числу которых относятся BSD, macOS и Linux. Все они построены на этой философии. А побочный эффект работы в такой системе — чувство правильности и цельности. Что так всё и должно работать: из кирпичиков, маленьких строительных блоков, которые сцепливаются в конвейеры любой сложности. Это же гениально.
Может, через много лет Томпсона и Ритчи канонизируют, причислив к лику отцов-основателей разумного компьютерного мира. А сейчас цифровые археологи продолжают откапывать всё новые факты из истории Unix.
Например, в 2014 году исследователь Лея Нойкирхер нашла [15] в дампах исходного дерева BSD 3 файл /etc/passwd [16] с паролями всех ветеранов, таких как Деннис Ричи, Кен Томпсон, Брайан В. Керниган, Стив Борн и Билл Джой.
Для хэшей использовался алгоритм crypt(3) [17] с максимальной длиной пароля 8 символов. Лея взломала их стандартными брутерами john [18] и hashcat [19]. Большинство паролей были очень слабыми. Только пароль Кена Томпсона не поддавался взлому. Даже полный перебор всех строчных букв и цифр (несколько дней) не дал результата. Неужели он использовал специальные символы? Лишь в 2017 году Найджел Уильямс в списке рассылки The Unix Heritage Society [20] раскрыл эту тайну. Пароль со всеми возможными символами оказался q2-q4!
: это первый ход пешкой на две клетки в описательной нотации [21] и начало многих типичных дебютов [22], что очень хорошо вписывается в бэкграунд Кена Томпсона по компьютерным шахматам [23]. Брутфорс на видеокарте AMD Radeon Vega64 занял более четырёх дней.
Некоторые из разработчиков Unix живы и здравствуют. Если хотите посмотреть, какие операционные системы и программы они используют на своих домашних компьютерах — вот галерея 2002 года [24] и 2015 года [25]. Каждого в электронном письме попросили сделать скриншот текущего десктопа сразу, как только они прочитают эти слова.
[26]
Десктоп Брайана Кернигана (октябрь 2015)
Деннис Ритчи (1941−2011) в 2002 году использовал необычную установку: его домашний клиент на NT 4 подключён по ISDN к удалённому серверу Plan 9 в центральном офисе Bell Labs.
Plan 9 [28] — инновационная ОС, основанная на концепции распределённых вычислений. Любая машина может использовать любые ресурсы с любой другой машины как собственные. Сейчас эту концепцию пытаются реализовать в виде контейнеров, VM и микросервисов, а там она реализована на уровне ядра ОС.
Дальше у нас Брам Моленар [29], автор многофункционального текстового редактора Vim:
[30]
Десктоп Брама Моленара (сентябрь 2002)
[31]
Десктоп Брама Моленара (ноябрь 2015)
Джордан Хаббард [32], один из сооснователей проекта FreeBSD:
[33]
Десктоп Джордана Хаббарда (ноябрь 2015)
P. S. К сожалению, Линус Торвальдс не смог сделать скриншот из своей консоли в текстовом режиме.
Будем надеяться, новое поколение современных разработчиков не забудет, что мы стоим на плечах гигантов.
Устанавливайте любые операционные системы на наших VDS с мгновенной активацией [34]. Сервер готов к работе через минуту после оплаты!
Автор: Анатолий Ализар
Источник [35]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/363477
Ссылки в тексте:
[1] можно отследить до истоков — до Unix: https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
[2] философией Unix: https://en.wikipedia.org/wiki/Unix_philosophy
[3] «Unix. Программное окружение»: https://en.wikipedia.org/wiki/The_Unix_Programming_Environment
[4] говорил в своей презентации Брайан Керниган: https://youtu.be/tc4ROCJYbm0?t=297
[5] конкретных примерах: https://prithu.dev/posts/unix-pipeline/
[6] /r/earthporn: https://reddit.com/r/earthporn
[7] /r/memes: https://reddit.com/r/memes
[8] https://reddit.com/r/memes.json: https://reddit.com/r/memes.json
[9] jq
: https://stedolan.github.io/jq/
[10] feh: https://feh.finalrewind.org/
[11] eog: https://wiki.gnome.org/Apps/EyeOfGnome
[12] Image: https://habrastorage.org/webt/q9/gz/pi/q9gzpi2oq4sdz82chpja3svrsry.jpeg
[13] Лес в Нидерландах: https://www.reddit.com/r/EarthPorn/comments/mqq1sj/found_these_old_trees_in_a_forest_close_to_my/
[14] Image: https://habrastorage.org/webt/zg/f5/my/zgf5mysfu7bxrtr4z0elqjnz080.jpeg
[15] нашла: https://habr.com/ru/post/470966/
[16] /etc/passwd: https://github.com/dspinellis/unix-history-repo/blob/BSD-3-Snapshot-Development/etc/passwd
[17] crypt(3): https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/man/man3/crypt.3
[18] john: https://www.openwall.com/john/
[19] hashcat: https://hashcat.net/wiki/
[20] The Unix Heritage Society: https://www.tuhs.org/
[21] описательной нотации: https://en.wikipedia.org/wiki/Descriptive_notation
[22] многих типичных дебютов: https://en.wikibooks.org/wiki/Chess_Opening_Theory/1._d4
[23] бэкграунд Кена Томпсона по компьютерным шахматам: https://www.chessprogramming.org/index.php?title=Ken_Thompson
[24] галерея 2002 года: https://anders.unix.se/2015/10/28/screenshots-from-developers--unix-people-2002/
[25] 2015 года: https://anders.unix.se/2015/12/10/screenshots-from-developers--2002-vs.-2015/
[26] Image: https://habrastorage.org/webt/j6/1y/5m/j61y5mpjaw4plw8uljqsyitlig8.png
[27] Image: https://habrastorage.org/webt/lh/6v/ne/lh6vnexvskc8ep0tw35ogwreb8e.gif
[28] Plan 9: http://p9f.org/dl/index.html
[29] Брам Моленар: https://en.wikipedia.org/wiki/Bram_Moolenaar
[30] Image: https://habrastorage.org/webt/l8/wh/a6/l8wha68vwmvp_cznlqmqinj2pla.png
[31] Image: https://habrastorage.org/webt/i5/_-/_o/i5_-_omrzcyo6nwgwszcakxw6gw.png
[32] Джордан Хаббард: https://en.wikipedia.org/wiki/Jordan_Hubbard
[33] Image: https://habrastorage.org/webt/mm/gd/zp/mmgdzpmpn4rcthzmpcgdekl92oi.png
[34] VDS с мгновенной активацией: https://vdsina.ru/cloud-servers?partner=habr323
[35] Источник: https://habr.com/ru/post/552536/?utm_source=habrahabr&utm_medium=rss&utm_campaign=552536
Нажмите здесь для печати.