Comments 135
Расширение функционала невозможно без лишних телодвиженийВопрос не в лишних телодвиженях, а в переусложнении, перегруженности, сопутствующих неудобствах и целесообразности. 10 однофункциональных программ, 1 десятифункциональная, 5 двухфункциональных? Однобуквенные флаги командной строки или многословные? Наверное, это тоже своего рода искусство — находить и грамотно воплощать баланс между необходимостью и удобством.
Благодаря текстовым интерфейсам, каждая команда должна знать как форматировать и это увеличение опций умножается на количество команд.
В powershell, благодаря объектной модели, команды более ортогональны. Отформатировать можно одними и теми же способами выхлопы разных команд.
# вывести процессы отсортированные по ID в грид
ps | sort id | ogv
# вывести все сервисы в названии которых есть SQL сгруппированные по статусу и отформатировать как таблицу с автоматическим размером колонок
gsv *sql* | sort status | group status | ft -au
Мы видим, что с годами количество опций резко увеличивается: как правило, записи темнеют слева направо (больше опций), и нет случаев, когда записи становятся светлее (меньше опций).
Опций не становится меньше из соображений обратной совместимости, я полагаю. Но, было бы интересно посмотреть на примеры, когда опции убирали за ненадобностью или еще по какой причине.
Но, было бы интересно посмотреть на примеры, когда опции убирали за ненадобностью или еще по какой причине.Обычно бывает как у ld:
-g
Ignored. Provided for compatibility with other tools.
…
-assert keyword
This option is ignored for SunOS compatibility.
…
-qmagic
This option is ignored for Linux compatibility.
-Qy
This option is ignored for SVR4 compatibility.
Обожаю текстовые интерфейсы ls. Вы в курсе, что вывод ls невозможно распарсить машиночитаемыми методами? Если вы думаете, что можно, то поздравляю, ваш песочек 1979 года высыпается с удивительной скоростью.
Текстовый интерфейс плохо работает. Он работает, но многие путают "могу сделать" и "могу сделать правильно". Основная проблема — отсутствие структуры и возможности его эскейпинга. Как мне отделить поле "f" от поля "g"? Могу ли я положиться на то, что разделительный символ не будет внутри поля "f"? Нет. Кто следит за целостностью юникод-символов?
Если вы думаете, что можно, то поздравляю, ваш песочек 1979 года высыпается с удивительной скоростью.Думаю что можно. Используйте опцию
-b
и меняйте \что-то по табличке.Конечно тут у вас ни простоты, ни надёжности… но распарсить — таки можно.
Текстовый интерфейс плохо работает. Он работает, но многие путают «могу сделать» и «могу сделать правильно».В 70е — первое было важнее… да и до сих пор важнее, иначе бы и C/C++ и PHP давно бы вымерли.
ls ---libxo и парсьте сколько хотите.
Либо что-то съелось, либо оно не работает.
Что значит "что-то съелось"? Типа в вашем парсере JSON бага? Пардон, но баги не относятся к концепту/архитектуре.
Я ж не знаю что вы написали. То, что я копирую к себе в консоль не является опциями ls.
ls ---libxo
ls: unrecognized option '---libxo'
Является.
LS(1) FreeBSD General Commands Manual LS(1)
NAME
ls – list directory contents
SYNOPSIS
ls [--libxo] [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]
[file ...]
вот здесь подробнее
А ну да, на Линукс как всегда такие мелочи пока завезли далеко невезде: systemd он погромче и монументальнее во внедрении.
В "свежих" убунтах пакеты нередко пятилетней давности бывают. Лет через 10, думаю, доедет, как это было с ключами find
типа -newermt
(сейчас и в Убунте есть, хотя я пользовался еще в середине нулевых).
Давайте лучше по версиям. У вас фряшная или гнушная ls?
У меня в системе
ii coreutils 8.30-3ubuntu2
Я же говорю, на фре я пользовался find -newermt
еще в середине нулевых, а появился он там еще раньше. До линуксов вообще же этот ключ доехал только в истекающем десятилетии, до убунты еще позже. То же прогнозирую и с libxo.
$ touch a b 'c d' d$'\xff'
$ ls -l
total 0
-rw-r--r-- 1 netch netch 0 May 1 18:46 a
-rw-r--r-- 1 netch netch 0 May 1 18:46 b
-rw-r--r-- 1 netch netch 0 May 1 18:46 'c d'
-rw-r--r-- 1 netch netch 0 May 1 18:46 'd'$'\377'
$ ls
a b 'c d' 'd'$'\377'
Она про себя пишет:
$ ls --version
ls (GNU coreutils) 8.28
да, недавно (как в 8.22 на RHEL7) этого ещё не было.
Вот чему я удивляюсь — что этот квотинг не сделали по умолчанию ещё лет 30 назад.
Ну про ключ -b вам уже сказали.
А теперь создайте файл с именем, содержащим кавычки. Не знаю, чем там думали лет 30 назад, но, наверняка, думали, что люди будут достаточно адекватны, чтобы не выходить из определенного подмножества символов. Вот точно что я не хотел бы видеть в имени файла — символов управления юникод. А тогда… 30 лет назад… был стандарт 8.3 на конкурирующей системе (сами знаете какой) и все файлы имели имена из нижней половины ascii
В чём проблема?
$ touch \' \" \'\" \"\'
netch@halinta:/var/tmp/x1>>
$ touch \' \" \'\" \"\'
$ ls -l
total 0
-rw-r--r-- 1 netch netch 0 May 1 22:06 "'"
-rw-r--r-- 1 netch netch 0 May 1 22:06 ''\''"'
-rw-r--r-- 1 netch netch 0 May 1 22:06 '"'
-rw-r--r-- 1 netch netch 0 May 1 22:06 '"'\'''
В шелле даже средствами POSIX shell (без bash'евских $'\x27' и т.п.) можно передать любой код, меняя кавычки и склеивая куски разного стиля квотинга. Ну кроме NUL и слэша, естественно (но это ограничения уже уровня FS, а не шелла).
> но, наверняка, думали, что люди будут достаточно адекватны, чтобы не выходить из определенного подмножества символов.
Обычно «они» и не выходят. Но ограничения всё равно нет.
> был стандарт 8.3 на конкурирующей системе (сами знаете какой) и все файлы имели имена из нижней половины ascii
Был. До сих пор после них в Windows case insensitive, но при этом локалезависимое, в результате можно увидеть в зависимости от настройки i<->I или i<->İ, ı<->I, ß<->SS, SZ или ẞ…
Я что имел в виду — файл действительно можно создать с практически любым именем, но выхлоп ls -l нужно все равно специальным образом обрабатывать, чтобы парсер следующей программы по пайпу не сломался. Ей-Богу, проще самому сделать системный вызов или библиотечный вызов и получить в скрипте нативный список или массив с именами файлов. А ls -l — несомненно хорошо для оператора, т.е. человека. Просто глазами посмотреть, что творится в ФС. Как бы автоматизация в целом и ad-hoc задачи по админству — это два разных слоя и их не нужно смешивать. Иначе получается плохо.
По остальному не возражаю.
Ну так это проблема известная и решается другими средствами. Например, ещё в середине 90-х publicfile от DJB ввёл стандарт передачи листинга каталога на основе netstring, где проблемы парсинга сведены к минимуму (и многие FTP клиенты были научены его понимать). А для локальных скриптовалок есть свои средства, которые не прогоняют через промежуточный текстовый формат — им не нужно парсить вывод всяких ls.
> Ей-Богу, проще самому сделать системный вызов или библиотечный вызов и получить в скрипте нативный список или массив с именами файлов.
Да, так и делают. Но есть контексты, где какая-то текстовая сериализация.
> Как бы автоматизация в целом и ad-hoc задачи по админству — это два разных слоя и их не нужно смешивать. Иначе получается плохо.
По моему опыту руления ISP, заметная часть ad-hoc задач таки перерастает во что-то посерьёзнее. Ну или всплывают обстоятельства, после которых таки даже к простым задачам надо подходить серьёзно — примеров можно привести тоннами.
tar x <filename
отлично работает. Тут одна опция.xvf или даже xf )
Их надо воспринимать как команды у git'а. tar czf, git commit — в чём разница?
лично мне git clone, git commit, git push представляются отдельными тулзами со своими параметрами, которые просто работают с одной областью — репозиторием.
поэтому для меня нет разницы между
tar -xvf file.tar.gz
# и
git checkout -b feature
но между tar -xvf
и git commit
определенно есть разница.
По похожей схеме устроены и команды dotnet, docker. Мне такой подход нравится.
И AFAIK, именно так git и устроен — пачка отдельных исполняемых файлов, по одному на команду. За счёт этого можно и новые команды относительно легко добавлять, просто добавив их в PATH под определённым именем.
лично мне git clone, git commit, git push представляются отдельными тулзами со своими параметрами, которые просто работают с одной областью — репозиторием.Они не только предствляются, но и являются отдельными тулзами. Лежат обычно в
/usr/lib/git-core
, он не в PATH
, так что просто так использовать git-clone
не получится, но если ручками добавить /usr/lib/git-core
в PATH
— без проблем. Собственно всё, что «основная» команда git
делает — это добавляет /usr/lib/git-core
в PATH и запускает, после этого, другую команду.tar acf <куда_сжать.tar.чем_сжать> <что_сжать>
tar xf <что_распаковать>
tar tf <где_посмотреть_файлы>
acf должен понимать все популярные форматы по расширению (gz, xz...)
Конечно, нельзя создать решение (стандарт) на века. Я это понимаю.
Если в доме обои криво поклеены, то не нужно стены перекраивать. Нужно решить те самые 0.5% проблем, не мешая огромной экосистеме работать.
Продолжая аналогию — проблема-то в том, что дом изначально построен на болоте, и стены со временем покосились. Но на протяжении десятилетий жители выбирали сделать еще одну подпорочку, а потом еще одну, и еще… Или вообще просто обои переклеивали.
Собственно это и есть разумная альтернатива. Только почему-то все попытки сделать новый, светлый, классный, дом кончались тем, что на новострой (Plan9, Singularity и так далее) «забивали» и оставались жить в старом доме. Может не так кривы те стены-то?
Сейчас, вон, очередную поделку пилят — посмотрим, чем закочится…
Соотвественно самый разумный способ — построить другой дом, не на болоте, чтобы когда тот, старый, развалится — было куда переехать.Все верно.
Только все попытки сделать новый дом кончались тем, что на новострой «забивали» и оставались жить в старом доме.На это тоже две вполне очевидные причины.
Причина первая: люди — биологические существа. Когда они выбирают технологии, предрассудки могут перевешивать логические доводы.
Причина вторая: бизнес жаден. Между вариантами «сделать костыль быстро и дешево» и «сделать как следует» практически всегда выбирают первый. Каждый такой выбор, как снежный ком, накапливает массу костылей и увеличивает число человекочасов, необходимых для ее исправления.
В итоге — стены кривые, но стоимость постройки нового дома с годами выросла до астрономических высот. Для мелкой кучки энтузиастов, которых кривизна волнует, эта стоимость непосильна, а для большинства «и так сойдет».
Достаточно сделать адаптер. В powershell если в pipe встроить обычную программу, она будет потреблять текст. Т.е. количество костылей уменьшается.
Теперь у вас есть «текстовые программы» и «нетекстовые». И вам нужно помнить что где, как и когда.
При этом, для удобства, некоторые вещи в Power Shell называеются так же, как «в старом мире» — но работают по другому.
При этом, для удобства, некоторые вещи в Power Shell называеются так же, как «в старом мире» — но работают по другому.
Насколько я знаю, в Powershell Core (он же pwsh) этих алиасов уже нет.
Теперь у вас есть «текстовые программы» и «нетекстовые». И вам нужно помнить что где, как и когда.
То же самое и с текстовыми командами — надо помнить формат каждой чтобы организовать их взаимодействие. И еще в каждую из них зашито некоторое подмножество нетекстовых. И еще метаформат нестандартизирован, так что организовать intellisense проблематично.
В этом классическом xkcd таки не учтен случай шлюзов, конвертеров и адаптеров между стандартами.
У powershell есть ровно три проблемы, которые помешали ему завоевать мир.
- Проприетарный governance. Такие вещи должны делаться всем миром, а не отдельно взятой компанией с love-hate отношениями с linux'ом.
- Дикая интеграция с c#. C# — клон java, он уродлив, ужасен и его никто не любит. Особенно душераздирающ он в контексте скриптинга, потому что там GryobannieClassiFabricGenratorSingleton.
- look-n-feed у powershell ужасный. Я понимаю, что они старались сделать унифицировано, но получилось равномерно неприятно.
Хотя попытка была хорошая, да.
Вы что-то путаете, фабрики генераторов синглтонов — как раз изобретение Java. В C# архитектурных астронавнов меньше, как и результатов их работы.
Объекты для передачи через pipe — это dead end. Объект — это же данные плюс код. Мы не хотим страдать от чужого кода, мы хотим данные.
Вот аннотированные структуры без боли и избыточности кода — это мечта. Как аннотировать структуру?… И тут мы не знаем, потому что у нас либо единообразный фашизм, когда точно известно о структурах всё, либо asn.1 безумие, которое невозможно юзать красивым образом, либо json-анархия, когда "строка" vs "список" — это вершина доступной типизации.
На самом деле хотелось бы иметь минимальную разумную иерархию типов, которая бы с одной стороны никого не вгоняла бы в фашизм чужой экосистемы (представим себе взаимосдействие пайпа из php, в rust и в python), а с другой стороны позволила бы точно различать "имя файла" от "имени пользователя" и "текст ошибки" от всего остального.
Нам нужен Очень Умный человек, который сделает настолько просто, насколько можно, но не проще.
Объекты для передачи через pipe — это dead end.
Объект — это же данные плюс код.
Это обеспечивает абстракцию и модульность.
Мы не хотим страдать от чужого кода, мы хотим данные.
Тогда вам не надо вызывать чужой код, иначе вы можете пострадать.
Каким образом вы можете обеспечить абстракцию и модульность, передавая код?
Вот у меня такая штука (текстовый пайп):
ssh user@arm.server foo list | ssh user@s390.server pprocess -p 2 | sort -u | sort -n
Предположим, мы передаём код. На arm.server у нас 32-битная armf7 архитектура под управлением ядра 3.13. На s390 у нас PPC под управлением FreeBSD, на локальной машине x86_64 под управлением Linu 5.5.
Я хочу спросить, в каком месте у нас тут модульность получается? Я могу использовать "модуль" на armf7 в пайпе на FreeBSD с PPC процессором? Конечно, нет. У них там всё другое. Они могут договориться по данным, но передавать код по сети — безумие.
Таким образом, передача объектов (кода с данными) хуже, чем передача данных.
… Просто представьте себе, если бы к кажому IP-пакету прилагался код для его интерпретации. Где наш интернет был бы?
ssh user@s390.server pprocess -p 2
но передавать код по сети — безумие.
Вы про какой код? Тут вроде у вас команды передаются, это не код? Еще вы, скорее всего, набираете это в браузере с неотключенным javascript.
Впрочем, вы совершенно правы, достоинства и недостатки они зависят от того, от чего именно мы хотим абстрагироваться. Если надо абстрагироваться от технологии в целом, то на границах должен быть наиболее простой переносимый интерфейс. Тут текст рулит. При работе внутри одной технологии можно абстрагироваться от деталей реализации конкретных понятий (например, хранится что-то или вычисляется на ходу).
ps | sort ws -desc | select -first 10 | select processname,cpu
Если вы вызовете ps без параметров он не выдаст COU — т.е. он абстрагирован от того какие именно характеристики нужны потребителю — это решается дальше по пайплайну. Он может не вычислять ничего и автору скрипта не надо думать о том, каким именно образом получается конкретная характеристика.
Так ведь всё очень просто же: передаются данные, а код уже присутствует на обоих сторонах пайпа.
Именно так сделаны все известные мне механизмы сериализации объектов.
Плюс, если мы говорим про шелл, методы объекта могут быть написаны на этом самом шелле. Не вижу проблем передать кусок скрипта по сети, даже на хост с другой архитектурой.
Вот если кто-то осилит такое — например, доведя ebpf или webassembly до совершенства, будет интересно. Хотя всё равно сомнительно.
Можно потребовать, например, только лямбды без сайд-эффектов. Такие хотя бы запускать можно неглядя.
Когда у нас код отдельно от данных, то это уже не объекты, а структуры. Да, на обоих сторонах для этих структур есть реализации (impl Struct
, да?), но передаются-то только данные.
Когда на вход пайпа передаётся объект, и на выходе пайпа принимается объект — я это называю "передаётся объект".
Чем отличается структура от объекта?
В основном — тем, что со структурой я работаю вот так: foo(bar)
, а с объектом — вот так: bar.foo()
:-)
И если в языках со статической типизацией разница может являться делом вкуса, то в языках с динамической типизацией, которыми являются шеллы, во втором случае запись получается куда короче.
Rust вполне справился с созданием ассоциированных с типами функций как раз для такого bar.foo(). Без необходимости таскать код с собой в объекте.
Ассоциированные типы обычно лучше работают в комбинации с трейтами (что опять же, позволяет оставить реализацию на усмотрение того, кто реализует трейт, вместо того, чтобы таскать код с собой).
Ключевая разница в том, что объект содержит в себе код. Вы не можете передать код вместе с данными по сети (без головоломных упражнений), а вот передать данные и ассоциированные с ними признаки по которым код можно выбрать (из локальных реализаций) — можете.
Да, но у Rust статическая типизация.
В языке с динамической типизацией не может быть ни трейтов, ни перегрузки фнукций. В итоге вы будете вынуждены указывать информацию о типе в имени функции, чтобы хоть как-то решить проблему конфликта имён. А я не хочу всякий раз писать bar.bar_foo()
вместо bar.foo()
.
Э… мы всё ещё про передачу данных или уже про язык программирования? Во что вам внутри вашей песочницы данные завернут — это уже дело десятое. Кому-то объекты сделают, кому-то структуры с трейтами, кому-то — структуры без трейтов и h-файлами. А кому-то вообще отгрузят махрового баша.
Интерфейс для передачи структур (аннотированных данных) должен содержать в себе столько информации, сколько нужно для выполнения этого, причём чем меньше, тем лучше.
Напоминаю исходную дискуссию о том, что следует передавать в пайпах. Варианты: текст без интерпретации, объекты (структуры с ассоциированным кодом на каком-то из языков программирования) или структуры данных с аннтоациями типов (чтобы языки программирования могли эти структуры использовать с богатой семантикой).
Там та же json-модель. Маловато будет. То есть если мне магически сейчас в шелле всё на это переключат — будет хорошо. Но ради этого никто не будет устраивать революцию масштаба systemd. Кроме того, бинарный формат нечитаем, и это плохо для отладки (особенно, отладки пайпов).
Нужны богатые типы, полезные и универсальные. Чтобы их придумать надо быть гением и визионарием невероятных масштабов.
А прочитать дальше первого абзаца? Не та же. Там 64 бита на теги, и тегов можно цеплять сколько угодно. Список зарегистрированных типов https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml уже довольно немаленький.
Для отладки же достаточно стандартизированной утилиты, ведь, например, тот же JSON мало кто читает руками, берут какой-нибудь jq, там. Соответственно, вопрос сугубо желания/времени.
Поискал. Пути к файлу до сих пор нет. Имени пользователя до сих пор нет.
Если говорить про теорию — может быть. Для практики кто-то это всё должен пойти и сочинить. И дело не в формате, а в списке того, что должно быть. open-ended список — не выход, потому что всех будет бесить, что кто-то поддерживает, кто-то нет. В спеке должен быть обязательный хороший список, который покроет все критические для успеха случаи.
Не, вот сначала хотите "минимальную разумную иерархию типов", а теперь каждый чих подавай. Противоречие.
Предложенный ими минимум не является разумным, потому что не решает базовые случаи, которые ожидаются быть решёнными.
Нет, предложенный минимум — как раз действительно необходимый минимум, типы из JSON плюс еще несколько базовых. Как орт-вектора. И система тегов даёт возможности расширять как угодно — в отличие от JSON, который не дает. Минимальность и ортогональность костяка — вот то, что разумно. А чьи-то персональные ожидания — субъективизм.
Минимальность и ортогональность костяка — вот то, что разумно.Ага. И потому все мы тут пользуемся Scheme, а про PHP и 1C все забыли.
Ой, извините, это я во сне в другую вселенную попал.
В нашей вселенной минимально-ортогональный костяк — проигрывает в 100 случаях из 100. А выигрывает — набор конструкций, которыми можно польваться для реальных задач.
Хотя иногда оказывается что что-нибудь реально нужное оказывается реализовано… неожиданно поздно. Например тип «имя файла» появился в C++ в 2017м году. А до этого как-то строками обходились…
Так что отсуствие тегов для имён пользователей — это не катастрофа, конечно… не неприятно.
А чем, на Ваш взгляд, путь к файлу и имя пользователя с точки зрения формата данных (не интерпретации, а именно формата) отличается от строки? Без подвоха, я догадываюсь, что отличие может быть, мне просто самому оно с ходу в голову не приходит, а Вы, я так понимаю, его уже знаете.
Я вот — совсем не знаю. Потому что, хотя бы, в разных ОС — разные форматы имени пользователя и пути к файлу, как по длине, так и по допустимым символам.
А чем, на Ваш взгляд, путь к файлу и имя пользователя с точки зрения формата данных (не интерпретации, а именно формата) отличается от строки?Ну хотя бы тем, к примеру, что в Linux «имя пользователя» — это вообще не строка, а число. А строковое представление — оно только для удобства пользователя и может быть в одной системе для одной и той же строки давать разные числа.
Но вообще я бы это всё вынес всё-таки в расширения — отдельно для Windows, отдельно для Linux, отдельно для будущих OS.
Сферическая ос в вакууме не даст записать в пайп путь к файлу, который не является путём к файлу, а ещё лучше, сделает нормализацию. Например, из /./././ сделает просто '/'.
У меня нет полного видения картины, но есть фрагменты, увы.
C# — клон java, он уродлив, ужасен и его никто не любит.Выдавать свои предрассудки за факты некрасиво и непрофессионально.
Да, они делают. Строят здание начиная с крыши. Подождём, пока дойдут до фундамента, дальше будет о чём поговорить…
Ну, кстати, инструментарий у них годный там снизу (никаких npm'ов).
Понимаете, ода текстовым форматам, которая появилась у Макилроя появилась, она ведь не на пустом месте возникла.
В 60е задача «как передать информацию от одной компьютерной системы к другой» (и даже внутри одной системы от программы, скажем, на Fortran, к программе на Cobol) — была весьма нетривиальной.
И использование «потока 8-битовых байтов с US-ASCII» разделителями было, в некотором, смысле, прорывом.
Сегодня… у нас всё ещё нет ничего лучше: 8-битовый байт принят всеми, US-ASCII (часто — как подмножества Unicode) — тоже, а вот чего-то сложнее… нет консенсуса.
Потому мы и используем эти интерфейсы до сих пор, что любые «более людчие»… не универсальны, увы.
А внутри отдельной, изолированной среды — вы можете устраивать что угодно… это ж ни разу не проблема.
У нас уже есть юникод. И даже есть 1 (один) язык программирования, который поддерживает unicode полностью и правильно.
На самом деле на минимальном уровне не хватает структурированности уровня полей. Это список, это словарь. Можно даже без int'ов, только строки. В каком-то объёме это решается json'ом, но его одного не достаточно для революции.
есть 1 (один) язык программирования, который поддерживает unicode полностью и правильно
Какой же?
Rust. Это единственный язык, который работает с unicode как с unicode, а не ASCII с "ещё байтами".
Hint: сколько символов в этой строке "אֶת דַלְתִּי הֵזִיז הֵנִיעַ, קֶטֶב हि"?
Если мне xterm и zsh при копипасте из Firefox ничего не напортили, то:
$ perl -CSDL -E 'use utf8; $a="א<05b6>ת ד<05b7>ל<05b0>ת<05b4><05bc>י ה<05b5>ז<05b4>יז ה<05b5>נ<05b4>יע<05b7>, ק<05b6>ט<05b6>ב <200b>ह<200b>ि<200b><200b>"; say length $a;'
41
$ echo א<05b6>ת ד<05b7>ל<05b0>ת<05b4><05bc>י ה<05b5>ז<05b4>יז ה<05b5>נ<05b4>יע<05b7>, ק<05b6>ט<05b6>ב <200b>ह<200b>ि<200b><200b> | iconv -t ucs-4 | xxd
00000000: 0000 05d0 0000 05b6 0000 05ea 0000 0020 ...............
00000010: 0000 05d3 0000 05b7 0000 05dc 0000 05b0 ................
00000020: 0000 05ea 0000 05b4 0000 05bc 0000 05d9 ................
00000030: 0000 0020 0000 05d4 0000 05b5 0000 05d6 ... ............
00000040: 0000 05b4 0000 05d9 0000 05d6 0000 0020 ...............
00000050: 0000 05d4 0000 05b5 0000 05e0 0000 05b4 ................
00000060: 0000 05d9 0000 05e2 0000 05b7 0000 002c ...............,
00000070: 0000 0020 0000 05e7 0000 05b6 0000 05d8 ... ............
00000080: 0000 05b6 0000 05d1 0000 0020 0000 200b ........... .. .
00000090: 0000 0939 0000 200b 0000 093f 0000 200b ...9.. ....?.. .
000000a0: 0000 200b 0000 000a .. .....
Совпадает.
Блин, и тут я должен поискать ненормализованные примеры unicode'а, но это так сложно… Скажите лучше мне сами, и с кратким после него — это 1 символ или 2?
*
гопническим акцентом*
А ты с какой нормальной формы будешь?
Этот вопрос даже теоретически, без языка программирования, неоднозначен. Рендеринг текста (даже неуникодного) — тяжелое занятие, и заметно отличается от "абстрактного текста".
Я "по-простому", а не "со всеми правильностями", считаю так:
й — один символ
и с combining accent — два
Итого, короче, не единственный язык (и иное было бы странно в языке, сделанном лингвистом и предназначенным для обработки текстов, действительно).
«Й» вам не «и» краткое! О важности нормализации Unicode
В D все строки юникодные (для других кодировок нужно использовать особые типы данных).
import std.stdio;
void main() {
dstring s = "אֶת דַלְתִּי הֵזִיז הֵנִיעַ, קֶטֶב हि";
writeln(s.length);
}
Вывелось 41. Если должно быть что-то другое, расскажите
У нас уже есть юникод. И даже есть 1 (один) язык программирования, который поддерживает unicode полностью и правильно.К сожалению, стараниями некоторых, unicode сделал всё только хуже.
В Linux/Unix, по крайней мере, можно считать что мир по прежнему использует «последовательность байт с разделителями US-ASCII». В Windows — всё ещё хуже.
К тому же Unicode — это решение совсем другой проблемы, передаче структурированной информации между программами он не помогает.
Лучше так, чем сделать идеальный протокол-фундамент, а дойдя до крыши обнаружить что его НЕ ХВАТАЕТ...
Вот, кстати, я себе их в список технологий на изучение внёс...
Тред оказался внезапно полезным.
Пока «протокола-фундамента» нет — говорить не о чем, а что используется для его прототипирования… дело десятое.
Как показывает опыт многих технологий, грамотные абстракции сверху важнее, чем детали реализации снизу. Реализацию потом подтянут, и, может быть, даже перепишут пару раз.
Вообще, идея о том, что строить что-то хорошее можно только после того, как тщательно продумал механизм реализации очень приятна (трудно сделать ошибку, когда база хорошо продумана), но она не позволяет leap.
Вот у вас пропасть и через неё надо мост. Вы сначала мост сдизайните, или потребуете, чтобы у вас были хорошие универсальные сваи были уже вбиты, а потом вы начнёте рисовать мост по сваям?
Как показывает опыт многих технологий, грамотные абстракции сверху важнее, чем детали реализации снизу.Это каких таких? OSI-протоколы? Или какой-нибудь «объектный» процессор?
Нет, не спорю, часть вещей действительно началась «сверху» (скажем Алгол или SQL… но гораздо чаще «высококонцептальные» разработки проигрывают работающему коду.
Реализацию потом подтянут, и, может быть, даже перепишут пару раз.Не работает. Вы можете переписывать реализацию сколько угодно раз — пока вашим продуктом никто не пользуется. Как только у вас появляются пользователи — происходит неверятно быстрая оссификация (и да, это русское слово).
Вообще, идея о том, что строить что-то хорошее можно только после того, как тщательно продумал механизм реализации очень приятна (трудно сделать ошибку, когда база хорошо продумана), но она не позволяет leap.Вы меня с кем-то путаете. Строить «что-то хорошее» можно как угодно. Строить что-то популярное можно, когда у вас есть база. А уж будет оно хорошим или нет — вопрос философский.
Вот у вас пропасть и через неё надо мост. Вы сначала мост сдизайните, или потребуете, чтобы у вас были хорошие универсальные сваи были уже вбиты, а потом вы начнёте рисовать мост по сваям?Всё зависит от пропасти и моста.
Но вот тут виртуальность оказывается сильно отличающейся от реальности. В реальном мире вы можете вначале прокинуть через пропасть верёвку и таскать через неё товары альпинистами. А потом построить хороший, качественный, «правильный» мост — и все начнут пользоваться им.
А вот в мире софта — всё не так. Вначале будут кидаться десятки верёвок и строится масса странных конструкций в духе World of Goo. Которые будут сваливаться в пропасть и над их конструкторами все будут смеяться. Но как только одна из них доберётся до другого конца пропасти… все перейдут на неё. Каким бы кривым и косым этот мостик не был бы.
После этого убедить хоть кого-то пользоваться другим, правильным, мостом — становится задачей на миллиарды долларов и десятилетия борьбы. Ну хотя бы снова вспомните про те самые мёртворождённые протоклы OSI, TCP/IPv4 и TCP/IPv6.
те самые мёртворождённые протоклы OSI, TCP/IPv4 и TCP/IPv6.
Серьезно? Все три используются, ну в6 еще не так широко, но всё же уже.
Я боюсь вы путаете протоколы OSI и cетевую модель OSI.
Вся история — это просто как эталонная лошадь ростом в метр и весом килограмм из парижской палаты мер и весов.
В 1960е — были два конкурирующих проекта по созданию «сети сетей». Была полукустарщина на деньги военных и была монументальная разработка под руководством профильного комитета.
И пока одни «пилили» работающую реализацию, другие «пилили» бабло — и порождали концептуальнейшие концепты и «грамотные абстракции».
Распил получился знатный. Бумаг было порождено немеряно. А вот ничего работающего… сделать не получилось. Ничего. Ну… почти ничего. X.500 был покоцан, избавлен от суперконцептуальности и превращён в LDAP. Всё остальное — «накрылось медным тазом». Целиком и полностью.
Но деньги-то хотелось пилить и дальше! И был придуман гениальный план: а давайте мы возьмём — и приспособим наши «чертежи звездолёта» к реально выпускающемуся танку? Ну и что, что там нет ни рулей стабилизации, ли реактивного двигателя? Скажем, что просто «концепт» не полностью реализован…
И вот — у нас уже целое поколение администраторов, которые веруют в семиуровневую модель и в то, что она имеет какое-то отношение к реальным сетям.
Это всё, конечно, классно, деньги «пилить» — завсегда весело… но к реальным сетям и к реальному миру отношения не имеет, извините. Там изначально были IPv0, IPv1, IPv2, IPv3 и, первая реально получившая популярность, IPv4. Которые не имеют никакого, вот совсем никакого отношения к ISO. И всё что выстроено поверх (NCP, TCP, SMTP/HTTP и всё прочее) — тоже никакого отношения к «концептуальным концептам» не имеют.
IPv6 — это, в принципе, не слишком большая модификация IPv4, которая внедряется (и, я думаю, в конечном итоге будет-таки внедрена) в течение десятилетий — потому что некоторые особенности IPv4 (в частности ограничение на общее количство адресов) оказались ну уж очень большой проблемой.
Так что… ни о каких «грамотных абстракциях сверху» вперёд реализации, как видим, и речи не идёт, и о «перепишут пару раз» — так тем более. Ну если речь не идёт о «перепишут пару раз пока этим мало кто успел начать пользоваться» — это нормально. Но пока этим мало кто пользуется… лучше с этим и не связываться, только со стороны следить. Ибо что вы будете делать если оно «не взлетит», а вы на него «завяжетесь»?
Вы ещё, говоря об исключениях из "ничего не получилось", забыли про X.25 который широко применялся в прошлом, например в финансовой сфере. Не уверен, правда, что он где-то жив и в наши дни.
Но вообще… там связь ровно обратная. X.25 — это 1976й год, начало работ над концептальными концептами — 1977й.
То есть вначале, да, была работающая спецификация (когда вместе сматывали сети разных провайдеров «с помощью скотча и проволоки» и меняли спецификацию под имеющуюся реализацию — см Telenet), а потом уже привлекли «архитектурных астронавтов», создали «грамотные абстракции» и «концептальные концепты».
Разумеется с соответствующим результатом: полный «нифига-то-я-не-обосрался».
То есть, по итогу, эксперимент получился всё-таки не на 100% чистый, рациональное, работающее, зерно, у этой всей деятельности таки изначально было… но с учётом масштаба получившигося «нифига-то-я-не-обосрался»… мне кажется это история достойна того, чтобы про неё знал и помнил каждый, кто интересуется наукой и техникой.
P.S. Если у вас есть примеры более эпичные — интересно о них узнать. Но у меня есть подозрения, что проекты, начинающиеся прямо сразу с «грамотных абстракций» разваливаются на полпути, ещё до выхода спецификаций… потому мы о них и не знаем ничего. История какой-нибудь Taligentа, наверняка, похожа, но так как там не участвовали комитеты, то этап «нифига-то-я-не-обосрался» оказался короток и смазан, документов не осталось, так что со 100% уверенностью ничего сказать нельзя.
Ага, PowerShell называется. Только красоты и лаконичности ему надо у кого-то занять
Текстовый вывод во многих ОС продолжает работать даже тогда, когда графическая подсистема упала напрочь.
Текстовый вывод нормально пролазит даже через очень медленные каналы передачи данных (попробуйте передать нормальную графику, столь же информативную, как текстовый вывод, через последовательный порт на 2400 бод).
Так что он (текстовый вывод) с нами, похоже, как минимум до тех пор, пока есть те же очень медленные каналы передачи данных, т.е. наверное, навсегда.
Текстовый вывод нормально пролазит даже через очень медленные каналы передачи данных (попробуйте передать нормальную графику, столь же информативную, как текстовый вывод, через последовательный порт на 2400 бод).
бинарный обмен пролезет и через медленные каналы передачи данных, т.к. может быть чуточку более сильно сжат. Другой вопрос, что процесс превращения данных в нечто для передачи может быть неявный для погромизда
Это как посмотреть. С одной стороны, текст тоже передается через каналы связи в бинарном виде (иногда даже сильно сжатым и зашифрованным в целях безопасности).
Но если мы об интерфейсе взаимодействия с конечным пользователем, то начинается самое интересное.
Если в канал связи уходят бинарные данные, то их надо еще как-то интерпретировать.
Текст и картинка могут интерпретироваться универсальным образом.
произвольные данные, не представленные текстом или картинкой нужно интерпретировать дополнительно, что порождает необходимость наличия у пользователя набора специализированных программ на все случаи жизни с постоянным пополнением их коллекции для новых случаев или модификации имеющихся программ.
Текст и картинка же могут формироваться на сервере (можно даже вместе, как в HTTP) и пользователю нужна только одна или две программы, которые ему это добро передают по согласованному сторонами стандартному протоколу. Таким образом, при появлении новых сущностей будет достаточно на сервере прикрутить интерпретацию данных в некоторое стандартное текстовое, графическое или текстово-графическое представление
Причем голый текст завсегда занимает заметно меньший объем.
Так что завсегда проще на стороне пользователя набрать текст команды и прочитать глазками текстовый вывод у себя в терминале, чем городить огород с передачей бинарных данных и их отдельной интерпретацией на стороне пользователя.
Другой вопрос, что исключительно на тексте замыкаться не имеет смысла, и для задач автоматизации как раз удобнее бинарные данные.
Но как только мы контактируем непосредственно с пользователем (без посредника в виде заранее написанной суперпрограммы) по медленному каналу, увы, но остается только текст, ибо обычный терминал будет доступен с гораздо большей вероятностью, чем эта суперпрограмма.
А потому текстовый вывод не исчезнет никогда и останется как минимум именно для данного применения.
на некоторый стандартный протокол
Ахаха.
Так и представляю, как представители разных дистрибутивов сели и за 5 минут сделали стандартный протокол и все согласились что он хорош.
Думаю на это уйдет еще лет 50, в результате чего будет десяток разных протоколов.
Жалобы, что использование памяти выросло в тысячу раз, кажутся немного смешными, когда (портативная!) машина стоит на порядок дешевле и имеет в четыре миллиона раз больше памяти.
И именно благодаря такому подходу мы имеем браузеры, жрущие гигабайты памяти, что бы обрабатывать скрипты в пару сотен КБ и графические движки с качеством графики на уровне мобилы и при этом тормозяшие на 6-ти ядерных процессорах и требующих видеокарт за 200 долл(привет, юнити!).
в 2017 году я купил Chromebook с 16 ГБ оперативной памяти за 300 долларов.А такие точно существовали в природе? Как так получилось, что сейчас за эти деньги Вы получите только 4Гб RAM? Зато eMMC там будет как раз 16 Гб, что заставляет меня задуматься о технической адекватности автора.
Только вот данная модель ноутбука по заверениям HP поставляется только с 2/4 Гб памяти.Точно-точно, правда-правда? Это вы так фразу Keep dozens of browser tabs open with 4 GB memory standard and up to 16 GB перевели? А до 16 GB LPDDR3; configurable with Intel® Core™ m7-6Y75 вы долистали или нет?
Сам процессор не поддерживает более 8 Гб.Однако на сайте Intel написано иное.
Просто владелец либо тоже не понимает разницу между RAM и eMMC либо сознательно вводит в заблуждение.Не знаю кто кого там вводит в заблуждение, но то, что ваша компетентность — ниже, чем у автора статьи, вы уже доказали. Продолжайте считать что вы всё знаете и дальше…
Поэтому ноутбуки с 16 Гб стоят от $900, хоть сама память стоит не так уж и дорого.Это они столько стоят новые, нераспечатанные. Ссылку на хромбук за $175 с 16GiB памяти я вам уже дал, хотя это сегодня, да. Про $300 в 2017м могу поверить, хотя сказать точно — имел ли автор статьи его или нет я, конечно, не в состоянии.
Оптовая цена не настолько низка, чтобы всю систему продать за $300.Возможно.
А на eBay продаётся не просто б/у, а восстановленный, после ремонта, а не просто со вскрытой упаковкой.А теперь окрываем глаза и читаем:
Хотя жалобы Макилроя на раздувание бинарников немного выходят за рамки этой статьи, я отмечу, что в 2017 году я купил Chromebook с 16 ГБ оперативной памяти за 300 долларов. (в оригинале Although addressing McIlroy's complaints about binary size bloat is a bit out of scope for this, I will note that, in 2017, I bought a Chromebook that had 16GB of RAM for $300).Ну и где вы тут видите слова «новый», «запечатанный» или что-нибудь подобное?
Да, есть люди не готовые переплачивать в 2-3 только за то, что им достанется вещь не «после ремонта», а «просто со вскрытой упаковкой». И есть в США целые фирмочки, которые специлизируются на восстановлении и продаже тех самых refubrished железок.
И цена $300 за приличную железку — вполне для них типична.
Вы же из tongue-in-cheek фразы чувака, которому посчастливилось где-то укупить задёшево неплохой конфиг — вывели сначала дикие теории о его некомпетентности, а теперь, когда вам показали, что дело не в нём — отыгрываете назад и делаете вид, что имели в виду что-то совсем не то, что написали.
Все хуже. Текст в зависимости от того, кто его интерпретирует — может быть разными сущностями. А уж сколько может быть коллизий. Например, HK vs НК. Т.е. по уму текст еще должен быть снабжен какой-то служебной информацией (вроде того — какой это диалект, хотя unicode с этим отчасти справляется).
Что-то я не вижу это автор утверждал противоположное. Напротив, он вроде как явно пишет:
У меня много претензий к PowerShell, но передача структурированных данных и возможность легко работать со структурированными данными без необходимости держать в голове метаданные, чтобы я мог передать их в нужные инструменты командной строки в нужных местах конвейера, не входит в число моих жалоб
Структурированный текст, например язык программирования, или JSON — тоже текст.
Только текст обеспечивает развитие, никакие другие "графические языки" и тому подобное — не взлетели.
Автор пишет что количество аргументов сильно увеличилось, приводит кучу доводов и предлагает оставить все как есть (свалить поддержку большого количество аргументов на разработчиков ради удобства пользователей) при этом сам же мимоходом отмечает (но почему-то не как последствия, а между прочим) что люди уже не читают маны, не знают аргументов используемых команд, а разработчики не успевают гарантировать функциональность всех ключей (раздел «баги»).
Автор в очередной раз рассказывает как хорошо в powershell со структурами, но почему-то в очередной раз не рассматривает недостатки этого подхода. Более того не указывает что в linux есть shell'ы с поддержкой структур, как раз вдохновленные powershell. Распространения они не получили. Лично я ими не пользуюсь, потому что не вижу в них потребности.
Очевидно что поддержка структур в выводе усложняет код и негативно влияет на безопасность и производительность, а в некоторых случаях и вовсе не нужна (например в cat). Где это не критично, разработчики и сейчас добавляют опции вроде -output json и далее вывод можно разобрать любой программой, хоть однострочником, хоть jq, хоть собственным парсером, в зависимости от требований пользователя к ресурсам и безопасности. Более того принципиальной разницы между структурой с пробелами и символом новой строки и json нет, это больше вопрос вкуса. Весь вопрос сводится к стандартизации — нужно ли заставить разработчиков поддерживать какой-то один стандарт во всех своих программах? Очевидно нет, так как цели и требования у всех разных. Более того это не возможно.
Конечно, добавление опций увеличивает нагрузку на мейнтейнеров. Но это справедливая плата за пользу, которую они приносят. Учитывая соотношение количества мейнтейнеров и пользователей, логично возложить дополнительную нагрузку на первых, а не на вторых.
Не учитывается, что мейнтейнеры часто энтузиасты. Для них разница между поддержкой чистого минимального кода и лапши из аргументов нередко критическая. В каком-то роде система пребывает в балансе — софт усложняется => энтузиазм угасает => разработка прекращается, потребность пользователей остается => появляется сторонний упрощенный форк и поддерживается пока баланс между удобством и поддержкой кода сохраняется. Даже я как пользователь при выборе софта из альтернатив предпочитаю более лаконичный вариант, в котором при необходимости смогу сам разобраться и что-то поправить.
Например, wc -w неправильно обрабатывает Юникод и т. д. Сказать, что «текст» — это универсальный формат, всё равно что сказать, что «двоичный» — это универсальный формат.
Так пайп не текст передает, а бинарные данные (удивительно что множество комментаторов на хабре не обратили на это внимание). Я могу и в tcpdump отправить поток. Само собой для соответствующего результата нужно использовать программу, ожидающую соответствующие данные. Как и в любой другой программе. Странно использовать программу для конвертации flac в mp3 и возмущаться, что она не конвертирует png в jpeg.
По крайней мере, благодаря инструментам с большим набором опций и функциональности пользователи Unix могут заменить гигантский набор дико несогласованных инструментов просто большим набором инструментов, которые, хотя и несогласованы друг с другом снаружи, но обладают некоторой внутренней согласованностью.
Что это значит для меня остается загадкой. Видимо что не каждый вывод одной программы может быть перенаправлен без изменений в другую программу. Это вполне логично, иначе каждому разработчику пришлось бы согласовывать изменения с сотней других разработчиков (вспоминаем что каждая программа ожидает определенные данные). Нужен нам комбинаторный взрыв? Не думаю. Стандартизированные структуры тут не помогут, потому что кроме фильтрации по полю N есть и разные форматы даты, системы счисления, даже нумерацию начинают с нуля и единицы. Получается нам нужен конвертер одних данных в других и механизм обмена данными. Механизм называется пайп, конвертер любая программа с stdin и stdout на ваш выбор.
Если кто-то хочет написать инструмент на основе «философии Unix», то у разных людей будут разные мнения о том, что означает «простота» или принцип «делать одну вещь»
Более того значение любого слова может не совпадать для различных людей. Это не мешает людям идти к одной цели, даже никак не связываясь друг с другом.
Это менее распространено в Linux с X, где правильная ментальная модель для большинства программ заключается в том, что копирование сохраняет указатель на данные, которые всё ещё принадлежат программе, из которой они копируются. То есть вставка не сработает, если программа закрыта.
Хм, речь идет про буфер иксов. Что ж, проверим на KDE с иксами. Скопировал текст из консоли, закрыл консоль, вставил текст в firefox, текст вставился. Аналогично в гноме. О какой ментальной модели в большинстве линуксовых программ пишет автор мне не понятно. И да, гигантские логи тоже копируются через буфер обмена.
Если представить, что набор инструментов командной строки вместе с оболочкой образуют язык, на котором каждый может написать новый метод, и в случае популярности метод эффективно добавляется в стандартную библиотеку, а стандарты определяются аксиомами
Вроде алиаса ll = ls -l. Аналогично можно писать функции и для более сложных случаев. Это к тому что часть проблемы можно решить (и решается) и на стороне шелла.
Усложнение команд консоли, 1979−2020