Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix

в 8:50, , рубрики: Bell Labs, jq, open source, UNIX, xargs, Блог компании VDSina.ru, брайан керниган, Деннис Ритчи, Кен Томпсон, конвейеры Unix, Настройка Linux, программное окружение, философия Unix, цифровая археология

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 1
Кен Томпсон и Деннис Ритчи

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'

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 указывает на обратный порядок сортировки. Вот и всё. Теперь у нас есть список авторов, отсортированных по количеству коммитов.

Просмотр мемов из /r/memes и установка обоев из /r/earthporn

Вы знали, что можно добавить “.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 с мемами, которые можно листать клавишами со стрелками, словно это картинки на локальном диске.

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 2

Или можно загрузить все изображения с помощью 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-задание, которое выполняется каждый час.

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 3
Лес в Нидерландах [2000×1333]

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 4
Гренландия [4032×3024]

Конечно, вместо /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 года. Каждого в электронном письме попросили сделать скриншот текущего десктопа сразу, как только они прочитают эти слова.

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 5
Десктоп Брайана Кернигана (октябрь 2015)

Деннис Ритчи (1941−2011) в 2002 году использовал необычную установку: его домашний клиент на NT 4 подключён по ISDN к удалённому серверу Plan 9 в центральном офисе Bell Labs.

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 6

Plan 9 — инновационная ОС, основанная на концепции распределённых вычислений. Любая машина может использовать любые ресурсы с любой другой машины как собственные. Сейчас эту концепцию пытаются реализовать в виде контейнеров, VM и микросервисов, а там она реализована на уровне ядра ОС.

Дальше у нас Брам Моленар, автор многофункционального текстового редактора Vim:

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 7
Десктоп Брама Моленара (сентябрь 2002)

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 8
Десктоп Брама Моленара (ноябрь 2015)

Джордан Хаббард, один из сооснователей проекта FreeBSD:

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 9
Десктоп Джордана Хаббарда (ноябрь 2015)

P. S. К сожалению, Линус Торвальдс не смог сделать скриншот из своей консоли в текстовом режиме.

Будем надеяться, новое поколение современных разработчиков не забудет, что мы стоим на плечах гигантов.


На правах рекламы

Устанавливайте любые операционные системы на наших VDS с мгновенной активацией. Сервер готов к работе через минуту после оплаты!

Почему работать в консоли настолько приятно? Так задумано отцами-основателями Unix - 10

Автор: Анатолий Ализар

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js