Настоящий Unix — не есть приемлемый Unix

http://mkremins.github.io/blog/unix-not-acceptable-unix/
  • Перевод
Командная строка Unix полна сюрпризов. Например, вы знали, что инструмент ls, который чаще всего используется для получения списка файлов в текущем каталоге, в версии OS X распознаёт не менее 38 разных флагов?

Я не знал, так что затвитил этот факт. И получил парочку ответов, один из которых заставил меня задуматься: действительно ли саму Unix нужно винить в этом?

Насколько я знаю, ни Linux, ни OS X не были спроектированы в строгом соответствии с философией Unix. Будет лицемерием основывать критику “Unix” только на этих производных от Unix, которые есть у нас сегодня.

Но я всё-таки попробую показать, как много проблем с интерфейсами командной строки в современных наследниках Unix восходят к корням самой Unix. В частности, я попытаюсь объяснить свой скепсис относительно идеи, что окружение командной строки Unix могло когда-либо поддерживать экосистему программ, каждая из которых хорошо выполняет одну функцию.

Но я немного опережаю события. Прежде чем я начну говорить об этом, давайте более пристально посмотрим на команду ls и попробуем выяснить, что конкретно она делает не так.

Много всего, но слабо


Разные версии ls распознают разные наборы флагов, но в целом эти флаги можно распределить по нескольким широким категориям. Пользователи ls применяют флаги, чтобы:

  • Определить формат выдачи. −C упорядочивает записи в аккуратную сетку; −m выдаёт разделённый запятыми «поток» записей; −1 выдаёт каждую запись в своей собственной строке; −q заменяет непечатаемые символы в названиях файлов вопросительными знаками.

  • Отобразить дополнительную информацию о каждом файле. −F добавляет символы к названиям каталогов (/), исполняемым файлам (*), симлинкам (@) и другим «особым» типам файлов; −s выдаёт размер каждого файла рядом с его именем.

  • Изменить порядок файлов. −r для списка в обратном порядке; −t для списка файлов по времени последнего изменения.

  • Включить или исключить определённые файлы. −a включает в список файлы, скрытые по умолчанию; −R показывает рекурсивный список файлов в подкаталогах текущего каталога.

Если опустить первую категорию флагов, то в остальных трёх есть кое-что интересное. Знатоки функционального программирования, в частности, могут увидеть в них нечто знакомое.

Так и есть — каждая из этих трёх категорий примерно соответствует единственной общей функции высшего порядка, которая работает с последовательностями!

  • Флаги для отображения дополнительной информации о каждом файле можно выразить в терминах map, которая применяет заданную трансформацию на каждый элемент в последовательности независимо от других.

  • Флаги для изменения порядка файлов можно выразить в терминах sort, которая использует заданное условие для попарного сравнения элементов и соответствующей сортировки.

  • Флаги для включения и исключения определённых файлов можно выразить в терминах filter, которая проверяет каждый элемент относительно заданного утверждения и отклоняет те, что признаны неподходящими.

ls кажется раздутой, потому что она действительно раздутая. Ряд функций высшего порядка могут взять на себя бóльшую часть функциональности, которая сейчас втиснута в ls в виде флагов.

Что пошло не так?


Идея того, что каждая программа должна вмещать в себе самодостаточную единицу функциональности, ни в коем случае не нова. Десятилетиями сторонники Unix превозносили достоинства конвейеров: «программ», созданных на лету соединением маленьких компонуемых фильтров друг за другом. В таком случае как можно объяснить эволюцию настолько концептуально простого инструмента как ls в сторону всё возрастающей сложности?

Экстремальная скупость командной строки Unix подсказывает одно возможное объяснение. Когда Unix изобрели, максимальная ширина экрана ограничивалась примерно 80 символами, а использование компьютера означало сидеть перед терминалом и набирать команды на клавиатуре. В таком окружении имело смысл пожертвовать удобочитаемостью и компонуемостью, чтобы втиснуть больше информации в минимально возможное количество символов.

В ту эпоху авторы самых популярных утилит сильно склонялись к тому, чтобы создавать сокращения везде, где только возможно. ls называется ls по той же самой причине, по которой её флаги представляют собой зашифрованные руны из одного символа вместо осмысленных слов или, не дай бог, целых фраз: она была разработана для небольшой группы узкоспециализированных экспертов в среде, где каждое нажатие клавиши, каждый символ на экране имел реальную и выразительную цену.

Аналогично и сами флаги являются сокращениями для наиболее общих сценариев реального использования. Зачем тратить время и добавлять шаг фильтрации к конвейеру, чтобы исключить скрытые файлы из выдачи, если 90% времени всё равно никто не хочет видеть скрытые файлы? Зачем отображать всю информацию о каждом файле, если 90% времени пользователю нужны только имена?

Такой образ мышления — что нажатия имеют высокую цену и что должны быть сокращения абсолютно для всего — определил многие из проблем ls и окружения командной строки Unix в целом.

«Универсальный интерфейс»


Но почему не написать более простую альтернативу ls — функцию, которая берёт произвольный каталог, или рабочий каталог по умолчанию, и возвращает список файлов из него, не обращая внимания на флаги? В конце концов, хакнуть Unix проще чем что-либо другое: если вам не нравится ls, можете заменить её.

Отвечу на этот вопрос гипотезой. Представьте язык программирования, в котором каждая функция принимает в точности один аргумент (строку) и возвращает в точности один результат (другую строку).

Ой, посмотрите — такой язык существует, и он называется шелл.

Unix позволяет программам общаться друг с другом и с пользователем исключительно через потоки символов. Вы не можете написать функцию, которая возвращает список файлов, потому что шелл не знает, что такое «список», не знает, что такое «файлы» и не сможет сказать вам разницу между «функцией» и «программой», даже если от этого будет зависеть его жизнь.

Программы не «принимают аргументы» и не «возвращают значения», они читают символы из stdin и печатают символы в stdout!

Пишите программы для обработки текстовых потоков, потому что это универсальный интерфейс.
Дуглас Макилрой, «Проектирование программ в среде UNIX»

Изначальные архитекторы Unix рассматривали «простоту» текстовых потоков как преимущество. Поэтому они отказывались накладывать любую структуру на данные, которые передаются между программами. Это решение, призванное избежать ненужной сложности, вместо этого просто перенесло излишнюю сложность дальше вниз по течению.

Помните первую категорию флагов ls — те флаги, которые мы не могли выдать за сокращения стандартных трансформаций последовательности? Выходит, что это просто сокращения для неформального кодирования условных списков файлов в виде строк, которые определённые другие программы (или, в некоторых случаях, человеческие существа) знают, как парсить.

Система неспособна предоставить абстракции, нужные пользователям. В ответ пользователи изобретают их заново, скудными, непоследовательными и не в тех местах. Это удручающе обычная практика.

Неприемлемый Unix


Знание истории информатики и ограничений, в которых формировались текущие ментальные модели, дарует нам своеобразную суперсилу: мы можем определить, когда необходимый прежде компромисс стал нелепым и устарел.

Многие проблемы юзабилити, которые поднял Дон Норман в своей критике Unix 1981 года, остались практически без изменений до настоящего времени. В качестве подарка мы разработали графические интерфейсы, которые держат «обычных пользователей» в стороне от командной строки, но по-прежнему предполагается, что «серьёзные разработчики» опустятся в явно негуманную среду, чтобы сделать там нечто осмысленное.

Вместо переоценки командной строки Unix с прицелом на улучшение юзабилити, когда современное оборудование уже не так ограничивает интерфейс, мы написали эмуляторы терминала, которые добросовестно воспроизводят ограничения середины 1970-х. Мы требуем от новых альтернативных оболочек совместимости с sh и слепо верим, что иерархические файловые системы — оптимальный способ организации информации.

Каковы шансы, что 40 лет назад мы как-то натолкнулись на лучший возможный интерфейс взаимодействия с компьютером? Другими словами, каковы шансы, что наши действия сегодня имеют смысл?

Даже самая ранняя версия Unix была только частной, имеющий недостатки реализацией философии Unix. Если мы хотим поощрить более широкое распространение философии, то не стóит защищать реализацию, преуменьшая её недостатки. Вместо этого нужно прямо взяться за эти недостатки. Строить системы, которые устраняют их, в то же время придерживаясь духа — если не буквы — принципов, на которых построен Unix.
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 116
  • +6
    Это всё, конечно, интересно, но где хотя бы предложение как решить эти проблемы? В последнее время стало актуальным написание целых рукописей на тему «что/почему так плохо в %SUBJECT%», при этом ничего не предлагая.
    • НЛО прилетело и опубликовало эту надпись здесь
    • +14

      Объектные шеллы типа powershell?


      Определить формат выдачи.

      Отдельная команда: ls | ft — форматировать как таблица


      Изменить порядок файлов. −r для списка в обратном порядке; −t для списка файлов по времени последнего изменения.

      ls | sort -descending


      Включить или исключить определённые файлы. −a включает в список файлы, скрытые по умолчанию; −R показывает рекурсивный список файлов в подкаталогах текущего каталога.

      Тут уж сама команда ls

      • +2
        PowerShell — это другая крайность: слишком длинные «параметры».
        • +3

          Там можно сократить до подстроки уникально идентифицирующий параметр


          Get-ChildItem -Recurse эквивалентно ls -r

          • 0
            В сугубо ограниченных случаях. Например в командлетах Exchange и других сервисов подобных сокращений не предусморено.
            • +2

              Насколько я знаю, что общепавершельное сокращение. Моджно ввести первые буквы параметра пока префикс однозначно его не определит:


              PS> ls -F


              Get-ChildItem: Parameter cannot be processed because the parameter name 'F' is ambiguous. Possible matches include: -Filter -Force.
              At line:1 char:4


              • ls -F
              • ~~
                • CategoryInfo: InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
                • FullyQualifiedErrorId: AmbiguousParameter,Microsoft.PowerShell.Commands.GetChildItemCommand

              PS> ls -fo


              Directory: C:\Users\ApeCoder

              Mode LastWriteTim


              У меня нет под рукой Exchange чтобы попробовать

              • +3
                Там нет алиасов, но сокращения параметров работают на уровне языка.
          • +1
            Конкретно команда ls имеет столько флагов по причине оптимизации.

            Если все реализовывать в виде последовательности фильтров, то на больших файловых системах, где в каталогах бывает > 10^6 файлов будет невозможно получить необходимый функционал либо он потребует неадекватного количества ресурсов.
            — Кроме того непонятен наезд на иерархичность файловых систем. В UNIX это вообще-то многосвязный граф (с возможностью использования механизмов предотвращения зацикливания при рекурсивном сканировании), а вовсе не строгая иерархия.
            • +2
              Если все реализовывать в виде последовательности фильтров, то на больших файловых системах, где в каталогах бывает > 10^6 файлов будет невозможно получить необходимый функционал либо он потребует неадекватного количества ресурсов.

              Почему?

              • +1
                Допустим, вам нужно получить имена файлов в текущей директории. Если использовать фильтры
                ls -l | awk '{print $9}'
                
                то у вас сначала выведется 9 колонок с метаданными и только потом вы возьмете нужную колонку (3-4% от начальных данных).
                А можно испольвать
                ls -1
                
                который сразу выведет только имя.
                • +1

                  Это если передавать данные, а не абстрактные объекты или лямбды

                  • 0
                    Расскажите про лямбды команде sort.
                  • 0
                    С объектами будет та же самая проблема. ls пойдёт на диск, считает все атрибуты всех файлов, создаст объекты соответствующего размера и передаст их в awk, который все эти атрибуты тупо дропнет. Получается, что 90% данных, переданных из ls в awk, переданы впустую, а ведь эта передача небесплатна.

                    Эффективнее иметь умный генератор данных и тупой обработчик, нежели тупой генератор объектов и умный обработчик.
                    • 0

                      А что, системный вызов stat уже позволяет выбирать какие атрибуты нужно считывать — а какие нет?

                      • +2
                        Нет, не позволяет, а какое отношение это имеет к вопросу? Я писал о переданных данных (из ls в awk), а не о считанных.

                        Кроме того, обсуждаемый вызов ls -1 будет использовать не stat(), а getdents().
            • 0
              ls | sort -descending

              Все бы ничего, но иногда обратная сортировка нужна не по первому полю, а, например, по размеру, а в именах файлов встречаются пробелы, и мы снова приходим либо к кавычкам-ескейпам, либо к более структурированному потоку данных, как в powershell. Грустно. Еще грустнее, если вспомнить, что в acsii есть символы «разделитель полей», «разделитель записей».
              • +2

                Почему структурированный поток — это грустно?

                • +1
                  Потому, что его еще никто нормально не сделал. Особенно powershell. Да и свои более врожденные недостатки у него есть.
                  • 0

                    Что такое нормально? Если взять любое X, то для него найдется момент времени T когда были только корявые прототипы, это не значит что любое X — это грустно.

              • –3
                Угу и учить отдельный язык для работы с ним. Одни уже написали язык для обращения пользователей к СУБД. Да-да я про SQL первоначально его делали для пользователей.
                • +4

                  Он и есть язык. Из за лучшего соблюдения Unix way учить легче — sort отсуортирует что угодно по чему угодно — не надо запоминать свитчи для каждого сочетания объекта и поля

                  • 0
                    Правда? А на имени файла «My 'file» он с ума не сойдет? А запоминать, под каким номером дата создания почему не нужно?
                    • +1

                      А почему он должен сойти?

                • 0
                  А чего тогда будет «скрытого» в этих файлах если они выводятся командой по умолчанию? Смысл тогда в их существовании?
                  • 0
                    Не захламлять вывод. В винде тоже есть скрытые файлы и тоже выводятся командой DIR
                    Смысл больше в том чтобы их спрятать с глаз долой, а не скрыть в них что либо.
                    • 0
                      Если команда ls по умолчанию будет их выводить как предлагается выше. Тогда и будет та самая захламленность вывода.
                      • 0
                        Видимо я не совсем хорошо проследил ветку, по умолчанию да ls не должна выводить скрытые файлы.
                    • 0

                      Почему вы решили, что в powershell команда ls по умолчанию выводит скрытые файлы?..

                      • 0
                        Человек так описал
                        " Включить или исключить определённые файлы. −a включает в список файлы, скрытые по умолчанию; −R показывает рекурсивный список файлов в подкаталогах текущего каталога.

                        Тут уж сама команда ls"

                        Отсюда мой вывод что команда ls выводит скрытые файлы.
                        • +1

                          Где именно тут написано, что команда ls в powershell выводит скрытые файлы по умолчанию?


                          Тут написано всего лишь, что управление выводом скрытых файлов или рекурсивностью обхода — это ответственность самой команды ls. По умолчанию и то, и другое выключено.

                          • –1
                            В приведенной цитате. Там ясно написано что ls без параметров выдает вариант с ключами -a и -R.
                            Как автор написал так я его и понял. Что именно имел ввиду автор знает он сам.
                            • 0

                              Где во фразе "Тут уж сама команда ls" вы увидели слова "по умолчанию"?

                              • 0
                                Там где у этой команды отсутствуют какие либо параметры. Это по моему мнению и есть вызов по умолчанию.
                                • 0

                                  Тут обсуждается команда и ее область ответственности в целом, а не работа при конкретном наборе параметров.

                                  • 0

                                    Я именно это и имел ввиду

                                    • 0
                                      Ну вам вероятно виднее что имел ввиду автор комментария.
                                      Я лично понял так как писал выше. Ощутил некоторое недоумение и задал вопрос автору комментария.

                                      Ну вот выше все и прояснилось. Вопрос снимается.
                  • +4

                    Не вижу проблем в соответсвии ls с идеологией unix, ведь все что делает ls — это:


                    > List information about the FILEs (the current directory by default)

                    Ну да, она так же позволяет выбрать формат вывода в удобной форме, но это необходимый шаг т.к. вывод происходит в виде обычного ASCII-текста а не объектов, это имеет свои плюсы и минусы конечно, но сути это не меняет, ls только выводит информацию о файлах в желаемом формате.


                    Кстати если вас так вдохновляет идеология Unix, возможно вам будет интересно почитать про Plan 9


                    Спасибо за статью!

                    • +1

                      Эдак про любую раздутую утилиту можно сказать "не вижу проблем с идеологией unix, да у нее 100500 фич — но это необходимый шаг т.к. мы пишем под винду где нет (не было) хорошего шелла для интеграции разных утилит".

                      • +2

                        Видимо вы меня не так поняли,


                        Я рассказал о том, что ls не выполняет никаких дополонительных фич, что вполне вписывается в идеологию unix. Она не копирует файлы, не меняет их атрибуты и т.п.
                        А все ключи здесь нужны только для настройки вывода, т.е. с помощью ключей вы задаете как имено вы хотите что бы она исполнила свою основную функцию.


                        Синдрома nero здесь не наблюдается :)

                        • +1

                          Почему вы считаете, что копирование файлов — это лишняя функция, а форматирование данных — нужная?

                          • 0

                            Потому что это часть основной функции программы, ls — это в первую очередь инструмент для пользователя, поэтому здесь так много настроек форматирования.


                            В случае если вам не нужен форматированный вывод вы можете воспользоваться ls -1 и другими более подходящими для этого инструментами, например find.

                            • +1
                              Потому что это часть основной функции программы

                              Поучему?


                              В PowerShell


                              Формат в виде таблички ft формат в виде html Out-Html открыть grid view c сортировкой и фильтором — ogv.


                              Это все надо запихивать в ls?


                              и в ps?


                              Вот так вывести процессы в виде таблички сгруппированной по имени
                              ps | sort Name | ft -GroupBy Name


                              Вот так вывести службы сгруппированные по статусу


                              gsv sql | sort Status | ft -GroupBy Status


                              Надо учить для каждой командой свои особые флаги?

                              • 0
                                Поучему?

                                Потому что в PowerShell вы оперируете объектами, а ls как и другие unix-tools на выходе дает обычный текст.


                                В этом и разница двух подходов.
                                В первом случае — это удобство и вся мощь работы с объектами.
                                Во втором случае — большая гибкость, и полная независимость от среды выполнения.


                                Вот так вывести службы сгруппированные по статусу
                                gsv sql | sort Status | ft -GroupBy Status

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


                                Но например с помощью nix'вых sort, sed и awk я могу творить просто невероятные вещи. Я могу удаленно выполнять команды в любом! шеле, получать и обрабатывать данные от них точно так же как от любых других програм, и при этом они не должны быть частью шела.


                                В этом вся прелесть работы с текстом. В этом подходе есть конечно и минусы, куда же без них.
                                Но так уж завелось, что в unix каждая программа написана отдельным разработчиком. Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.


                                Надо учить для каждой командой свои особые флаги?

                                К сожалению да.

                                • +2
                                  Но например с помощью nix'вых sort, sed и awk я могу творить просто невероятные вещи. Я могу удаленно выполнять команды в любом! шеле, получать и обрабатывать данные от них точно так же как от любых других програм, и при этом они не должны быть частью шела.

                                  В принципе текстовые потоки совершенно так же обрабатываются этими командамию. То есть можно из cmd запустит powershell sort и он отсортирует поток строк.


                                  Коммандлеты представляют собой отдельные компоненты — они не обязаны быть частью шелла — вы можете написать свой шелл с другим синтаксисом, главное использовать те же интерфейсы — концептуально то же самое.


                                  Вот PowerShell type provider для F# позволяет использовать команды powershell в F# с синтаrсисом F#


                                  Только текстовый шелл использует самый простой интерфейс — просто поток. И самый бедный. Вы можете привести бедный интерфейс к богатому и наоборот.


                                  В этом вся прелесть работы с текстом. В этом подходе есть конечно и минусы, куда же без них.
                                  Но так уж завелось, что в unix каждая программа написана отдельным разработчиком. Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.

                                  Так же в винде есть независимые поставщики командлетов — CISCO например


                                  Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.
                                  Надо учить для каждой командой свои особые флаги?
                                  К сожалению да.

                                  Это значит что не на отлично, а что просто там другое соотношение компромиссов между простотой использования и простотой внутренного устройства, более привычный вам

                    • 0
                      Организовать файловую систему так, что для ls и флагов не потребуется.
                      • 0
                        Можете поподробнее? Что должна делать ФС, чтобы при перечислении записей в каталоге не понадобилось никаких флагов? Или вы предлагаете отказаться от каталогов вообще и, соответсвенно, от ls и ее флагов?
                        • 0
                          Как при проектировании классов
                          1) правильные имена
                          2) не более 3-переменных в классе

                          Ну это я так, абстрактно посмотрел…
                          • 0
                            Я вас, похоже, не понял изначально. Вы говорили об именовании файлов и папок, а я подумал, что вы саму ФС предлагаете чем-то таким хитрым заменить.
                            • 0
                              Это уже Apple делал в iOS. Там теперь точно ls не работает без jailbreak
                      • +8
                        Почти каждый день я пользуюсь командами ls, ps, cd и прочими. Возможно у них есть какие то проблемы. Но я бы сказал у них есть очень серьёзный плюс, я ими пользовался 10(а кто то может и 40) лет назад, и с тех пор ничего для меня не поменялось. Да может за 10 лет там добавили 5-6 редких флагов. Но старые не поменялись. Я перехожу от дистрибутива к дистрибутиву линукса(а также QNX/BeOS/OS X итд), набираю ls и вижу то что ожидал. И никому в голову не пришло что давайте сделаем команду ListDirectoryContents так же явно понятней, новичкам будет проще.
                        И это по моему немаловажная ценность консоли, она может быть не идеальна, но ты изучаешь её один раз и потом не имеешь проблем с ней, а просто берешь и работаешь.
                        • +1
                          Мой прадед пользовался счетами.
                          Мой дед пользовался счетами.
                          Мой отец пользовался счетами.

                          Зачем нам изобретать калькуляторы и компьютеры, если есть проверенные веками счеты?
                          Берешь их, изучаешь один раз и просто берешь и работаешь…
                          • +7
                            Рассуждения в статье — это не «давайте изобретем компьютер вместо счет», это «давайте сделаем еще одни счеты, круглые, со стразиками и будем ими пользоваться если считаем котят».

                            Нужна тебе команда выводящая в каком-то особенном виде? Что мешает написать один раз скрипт ListInMyCoolFormat на основе того же ls и пользоваться им? Нет, блин, надо целую философию развести на пустом месте…
                          • +1
                            Почти 18 лет пользуюсь то HP-UX, то разными linux дистрибутивами, то вот сейчас на MacOS, и по-прежнему на Linux. Это для меня инструменты, можно сравнить их с молотком. Однажды научившись ими пользоваться я все еще хорошо владею ими. Как и молотком:) можно наверно сделать более совершенный инструмент, но не нужно. Он совершенен в своем несовершенстве.
                            • +2
                              И никому в голову не пришло что давайте сделаем команду ListDirectoryContents так же явно понятней

                              Вообще-то пришло, в большинстве командных интерфейсов используются длинные параметры с автодополнением: Cisco (и многочисленные клоны), NetApp, IBM TSM, PoSH.
                              • 0
                                А не скажете, как тогда родился этот зоопарк из halt\reboot\shutdown -xxx? При этом, я если честно до сих пор не знаю, как нормально выключить линукс-систему
                                • 0
                                  А тут зоопарк, при чём разных линуксах по разному. Но зачастую halt и reboot одно и тоже с разным поведением а вот shutdown имеет параметры которых может не быть в halt/reboot.
                                  Но в мане гентыы допустим сказано:
                                  Under older sysvinit releases, reboot and halt should never be called directly. From release 2.74 on halt and reboot invoke shutdown(8) if the system is not in runlevel 0 or 6.
                                  This means that if halt or reboot cannot find out the current runlevel (for example, when /var/run/utmp hasn't been initialized correctly) shutdown will be called, which might
                                  not be what you want. Use the -f flag if you want to do a hard halt or reboot.

                                  Получается что лучше всего использовать shutdown с нужным ключем.
                                  • 0
                                    shutdown -r now еще работает в нашем быстро менябщемся мире?
                            • –2
                              По другому никак, многие вещи можно сделать только в первичной обработке, т.к. после вывода останется только список файлов, который например уже не отсортировать по размеру, ну и для удобства некоторые параметры добавлены, как известно «буква закона» и «дух закона» — разное.
                              • +1
                                после вывода останется только список файлов, который например уже не отсортировать по размеру

                                ls -1 | xargs stat -c '%10s %n' | sort | cut -f 2 # или как-то так
                                • 0

                                  Все неправильно сделал, надо было сначала бутнуться в линукс и проверить, вот так надо:


                                  ls -1 | xargs stat -c '%s %n' | sort -n | cut -f 2 -d ' '
                                  • 0

                                    И всё ещё неправильно. В имени могут быть пробелы и даже переносы строк. Правильно — переписать всё на Си, что в ls и сделали.


                                    Нет ничего удобнее, чем вбить ls -lrt и посмотреть последние изменения в каталоге. А ещё никто не мешает сделать удобные для запоминания алиасы:
                                    alias ListFilesSortedByLastModificationTime='ls -lrt'

                                    • 0
                                      И всё ещё неправильно. В имени могут быть пробелы и даже переносы строк.

                                      ls -1 -Q --quoting-style=escape | xargs stat -c '%s %n' | sort -n | cut -f 2- -d ' '

                                      Done.


                                      Правильно — переписать всё на Си, что в ls и сделали.

                                      Спорно.


                                      Нет ничего удобнее, чем вбить ls -lrt и посмотреть последние изменения в каталоге. А ещё никто не мешает сделать удобные для запоминания алиасы:
                                      alias ListFilesSortedByLastModificationTime='ls -lrt'

                                      А вот про это я вообще ничего не говорил.

                                      • 0

                                        Не сочтите за грубость, но это тоже не будет работать:)


                                        touch 'troll'$'\n''file'

                                        Навскидку, как это правильно можно было бы сделать в bash (на самом деле так делать не надо, но демонстрация проблем с экранированием символов в шелле исчерпывающая):


                                        #!/bin/bash
                                        
                                        FILES=()
                                        SIZES=()
                                        i=0
                                        while read -rd $'\0' file; do
                                            FILES+=("$file")
                                            SIZES+=("$(wc -c < "$file") $i")
                                            ((i++))
                                        done < <(find -mindepth 1 -maxdepth 1 -type f -print0)
                                        for l in "${SIZES[@]}"; do
                                            echo $l
                                        done | sort -n | while read _ n; do
                                            printf '%q\n' "${FILES[$n]}"
                                        done

                                        Это из коллекции "1000 и один способ выстрелить себе в ногу в Shell". Если вы всё ещё полагаетесь в скриптах на вывод команды ls, настоятельно рекомендуется к прочтению, и это тоже.


                                        У некоторых людей такой юниксвейный подход к проектированию интерфейсов вызывает глубокую депрессию.

                                        • 0

                                          Более-менее нормально выводит


                                          ls -Q --quoting-style=shell-escape[-always]

                                          Не уверен чья это вина, может быть даже ls. Почему он не обмазывает бэкслэшами кавычки?

                                          • 0

                                            В Shell другие правила экранирования спецсимволов, которые ls не учитывает. Более правильно экранирует printf %q. И всё же лучше не полагаться на это, а ls может оказаться без этих расширений (busybox). В идеале должно получиться вот так: $'troll\nfile'

                              • НЛО прилетело и опубликовало эту надпись здесь
                                • +2
                                  собственно сортировка и управление порядком.

                                  Сортировка и есть управление порядком


                                  4. где-то во всем этом теряется информация о формате вывода: ls ею уже не управляет, а остальные программы работают с потоком записей, форматирование уже не их задача, так что нужно указать еще один компонент команды, что-то вроде такого:

                                  ls | sort --field=modification-time | reverse | print --field=name


                                  Powershell:


                                  ls | sort LastWriteTime -d


                                  • sort занимается порядком, в том числе и по убыванию
                                  • формат вывода определяется конфигом на основании типа объекта
                                  • если зхочется выбрать одно поле можно воспользоваться select или % (foreach)
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                    • 0

                                      Конфиг может влиять на записанные скрипты если они переводят объекты в строки и не казывают явно как.


                                      Согласен, что reverse бывает и другой но это концептуально опять не требует потоков данных. Они как в LINQ могут строить дерево выражений и отдавать провайдеру файловой системы, например. Без дополнительной сортировки

                                      • 0

                                        Любую задачу управления порядком можно свести к сортировке.

                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          • 0

                                            Тем не менее, в конкретном случае разворота последовательности этот самый разворот прекрасно вписывается в операцию сортировки как философски, так и практически.

                                            • НЛО прилетело и опубликовало эту надпись здесь
                                            • 0
                                              т.к. сортировка требует всего массива элементов в памяти.

                                              Не требует.
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                • –1
                                                  Пузырёк прости Господи. Загружаем два элемента, сравниваем, меняем местами при необходимости. Эффективность около нуля правда.
                                                  • 0

                                                    Есть специальные алгоритмы для блоковой сортировки в условиях недостатка памяти, но не помню какие

                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • 0
                                                        А откуда тут взялась сеть и объёмы, превышающие наличествующую память?
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                        • 0

                                          Особенно замена ls -R на "чистый" ls будет очень эффективна :)

                                        • 0

                                          Боюсь, автор недопонял философию unix: "Делайте что-то одно, но делайте это хорошо".
                                          ls делает одно дело — выводит список файлов. И делает это настолько хорошо, что мне больше ничего не нужно, когда я хочу посмотреть список файлов.
                                          Писать "ls -la" куда удобнее, чем ls | sort | grep | sed | awk ...


                                          ls кажется раздутой, потому что она действительно раздутая.

                                          Она может показаться раздутой для программиста, но для пользователя она очень проста и лаконична. Философия unix, насколько я могу судить, старается поворачивать программы и интерфейсы лицом к пользователю. Пусть даже программисту придется постараться для этого.

                                          • 0
                                            Ой, беги, дядь Мить. (с).

                                            Но почему не написать более простую альтернативу ls — функцию, которая берёт произвольный каталог, или рабочий каталог по умолчанию, и возвращает список файлов из него, не обращая внимания на флаги?

                                            Ну так понятно — раз так в 500 удобнее работать с буфером в своей памяти, в котром лежать данные типа «запись», структура и последовательной полей которой известна, чем читать строку символов, ее парсить в ту же запись — удобное внутреннее представление, чтобы отфильтровать. А потом окажется, что в новой версии легковесная ls выдает больше или меньше полей, или меняет последовательность, и старые программы-фильтры сдохнут. Или придется добавлять флаг вида «дай новый более удобный вывод», что опять приводит к раздутию.
                                            А потом, как всегда внезапно, придет осознание, что для наиболее частого сценария надо вместо одной команды запускать конвейером две, причем вторая будет просто тупо брать первое поле — имя файла, выкидывая остальное, делая сериализацию/десериализацию данных пустой тратой процессорного времени. Альтернатива — опять же добавить флагов вида «дай краткую инфу-дай полную инфу».
                                            Т.е. как ни крути, раздутие будет. Философия «сложим все из кирпичиков» хороша, но не универсальна. Как обычно — любая догма, как «запихать все в одну программу», так и «всегда разбивать на кирпичи», проигрывает взвешенному подходу.
                                            • 0
                                              Представьте язык программирования, в котором каждая функция принимает в точности один аргумент (строку) и возвращает в точности один результат (другую строку).

                                              Ой, посмотрите — такой язык существует, и он называется шелл.

                                              Вообще функции в sh получают произвольное количество аргументов и позволяют вернуть только код возврата (одно число).

                                              • 0
                                                Программы не «принимают аргументы» и не «возвращают значения», они читают символы из stdin и печатают символы в stdout!

                                                Что-то в мане по exec написано, что можно аргументы массивчиком передавать, а ещё и массивчик с environment variables. Та и в мане по exit статус тоже присутствует. Что вообще имелось ввиду под таким громким высказываением?

                                                • –2

                                                  Статья — какое-то непотребство дилетанта-графомана. А вот за комментарии вам, господа, огромное спасибо! Полезной и интересной информации великое множество.

                                                  • 0
                                                    Кстати, у *nix при всех его субъективных недостатка, которые, на мой взгляд, есть его достоинства есть одна черта, что поднимает его выше windows. От версии к версии парадигма *nix остается одной и той же, от одного уровня абстракции поднимаемся к другому, следуя принципам наследования объектов. Проще говоря, могут меняться частности, названия демонов, команд итд. Но все остается логичным и понятным. Если что-то не знакомо всегда через man можно все выудить и во всем разобраться. С первого знакомства с Unix и до сих пор это работает. Google почти так же хорош для поиска ;) как man для понимания *nix.
                                                    • +1

                                                      А что в винде так принципиально и несовместимо поменялось со времен NT? Та же эволюция

                                                      • 0
                                                        Да там каждую версию революция. WinAPI, DDE, OLE, MFC, COM, ActiveX, .NET, вот сейчас платформа для так называемых новых приложений, название которой я даже не утруждаюсь запомнить.
                                                        • 0

                                                          Дык это все ж друг друга не отменяет. Часть вообще на разных уровнях абстракции (COM <- ActiveX <- OLE). И все это поддерживается с момента изобретения. Какая революция?

                                                          • +3
                                                            И все это поддерживается с момента изобретения.

                                                            Это одна из проблем всего этого вороха технологий.
                                                            Какая революция?

                                                            Каждый раз настоятельно рекомендуют использовать последнюю выдуманную ими фигатень. И эта фигатень кардинально отличается от предыдущей, а пишущие на старой фигатени чувствуют семя ретроградами.
                                                            • +3
                                                              Это одна из проблем всего этого вороха технологий.

                                                              То есть надо не поддерживать обратную совместимость?


                                                              Каждый раз настоятельно рекомендуют использовать последнюю выдуманную ими фигатень. И эта фигатень кардинально отличается от предыдущей, а пишущие на старой фигатени чувствуют семя ретроградами.

                                                              То есть получается что проблемы чисто эмоционального характера — чувство себя ретроградом?


                                                              Мне кажется, что вы не очень разбираетесь в аббревиатурах:


                                                              DDE это часть WInAPI
                                                              MFC — бибиотека поверх winapi для C++


                                                              COM — объектно-компонентная технология построения приложений
                                                              ActiveX — COM объекты с поддержкой автоматической регистрации
                                                              OLE — набор COM интерефейсов для встраивания компонентов друг в друга


                                                              .NET — единственная отдельностоящая технология здесь но тесно связанная с остальными

                                                              • 0
                                                                То есть надо не поддерживать обратную совместимость?

                                                                Надо быть последовательным, и развивать старые интерфейсы, а не забрасывать их и делать новые.
                                                                То есть получается что проблемы чисто эмоционального характера — чувство себя ретроградом?

                                                                Не только. Как я уже написал, старые интерфейсы не развиваются. То есть программируя на своём любимом и знакомом старом интерфейсе, ты лишаешься доступа к новым технологиям.
                                                                Мне кажется, что вы не очень разбираетесь в аббревиатурах

                                                                Да я вообще утрировали, подгоняя под зарисовку «Фатальный недостаток», которая прекрасно показывает путь развития Windows.
                                                                • +1
                                                                  Надо быть последовательным, и развивать старые интерфейсы, а не забрасывать их и делать новые.

                                                                  Как я уже написал, старые интерфейсы не развиваются.

                                                                  Что именно не развивается из перечисленного?


                                                                  Да я вообще утрировали, подгоняя под зарисовку «Фатальный недостаток», которая прекрасно показывает путь развития Windows.

                                                                  Не получилось ли так, что утрирование иказило картину?

                                                                  • –2
                                                                    Что именно не развивается из перечисленного?

                                                                    Раз
                                                                    Dynamic Data Exchange (DDE) — механизм взаимодействия приложений в операционных системах Microsoft Windows и OS/2. Хотя этот механизм до сих пор поддерживается в последних версиях Windows, в основном он заменён на более мощные механизмы — OLE, COM и Microsoft OLE Automation.

                                                                    Два: OLE заменён на ActiveX.
                                                                    Три:
                                                                    Microsoft отказалась от поддержки ActiveX в Metro интерфейсе Internet Explorer 10 в Windows 8. В 2015 году в Microsoft Edge, замене для Internet Explorer, поддержка ActiveX прекращена, отмечая конец технологии в веб-браузерах Microsoft.

                                                                    Как видите, чёткая линейная история забрасывания продуктов, которую я построил по данным из Википедии за 3 минуты.
                                                                    • +1

                                                                      Как вы себе представляете "развитие" DDE-то? Куда ей там дальше развиваться?


                                                                      Говорить, что OLE заменили на ActiveX — тоже некорректно. Это две версии одной и той же технологии.


                                                                      Прекращение же поддержки ActiveX в браузере было давно ожидаемым шагом. Просто потому что эта технология слишком небезопасна и платформо-зависима для веба.

                                                                      • 0

                                                                        Еще можно посмотреть, что случилось в других браузерах за это время. Кто поддерживает NPAPI например

                                                                        • 0
                                                                          Как вы себе представляете «развитие» DDE-то?

                                                                          Так его же заменили на OLE и прочее. Вместо развития, да.
                                                                          • +1

                                                                            Не уходите от вопроса. В каком направлении могла развиваться эта технология?

                                                                            • 0
                                                                              Я не в теме программирования под Windows. Но ведь в OLE и прочем декларируются какие-то улучшения, из-за чего и призывают отказываться от DDE. Вот эти улучшения и есть то самое направление.
                                                                              • +2

                                                                                DDE — это технология, основанная на пересылке оконных сообщений между процессами.


                                                                                OLE — это технология, основанная на объектном подходе и, в основном, внутрипроцессном взаимодействии.


                                                                                Они отличаются как сокеты и С++ — это ж совершенно разные вещи!

                                                                                • 0
                                                                                  Технологически — да, но по использованию — нет. Ведь смысл один и тот же — обернуть, скажем, графический объект или электронную таблицу в некий контейнер и впихнуть в текстовый документ. У нас получается так же некий «сервер», как в OLE, котрый будет заниматься отрисовкой. Нет?
                                                      • 0
                                                        После таких обсуждений почему то начинаю любить Майкрсофт,
                                                        • +4
                                                          Предлагаю немного противоядия:
                                                          https://geektimes.ru/post/102179/
                                                          https://geektimes.ru/post/285682/
                                                        • –2
                                                          О, еще одна статья с абстрактными рассуждениями о недостатках идеологии *nix, в которой обсуждается не сама система а шелл. Шелл больше предназначен для интерактивной работы в нем и в выборе строгость vs удобство использования удобство побеждает. Тоже самое про сокращение команд, удобнее написать ls -l, чем ListDirectory --long-listing-format.
                                                          Хотите работать со структурированными данными? Возьмите любой язык программирования и работайте напрямую с сисколами, вызовами функций библиотек и тд. В реальности даже не придется доходить до таких крайностей и можно просто запустить интерпретатор python/php/ruby/etc в интерактивном режиме, будет как раз тот структурированный вывод, работа с объектами и все остальное, что вы так хотите. Попробуйте, если сможете проработать в таком шеле неделю пишите статью на хабре о уникальном опыте, но вероятнее всего такая работа надоест через 10 минут, т.к. по сравнению с башем и coreutils занимает гораздо больше времени при сомнительных плюсах.
                                                          • –1

                                                            Напишите, оценим. Критикуя — предлагай. Должно быть достаточно тривиально реализовать это все. Начните с написания своего шелла, (простой интерпретатор неделя работы, можно взять луа или что-то подобное) затем запилить протокол обмена данными, думаю максимально эффективно будет взять простой джейсон на каждый объект.

                                                            • 0

                                                              Черт как-то не заметил что перевод

                                                            • –3
                                                              ls называется ls по той же самой причине, по которой её флаги представляют собой зашифрованные руны из одного символа вместо осмысленных слов или, не дай бог, целых фраз

                                                              ls называется ls из соображений эргономики, чтобы можно было быстро получить список файлов в директории нажатием трёх клавиш, а не путём написания сочинения на тему "dear computer, please print the list of the files in the current directory for me".

                                                              • –1
                                                                Никто не заставляет пользоваться флагами, пожалуйста обрабатывайте вывод чем угодно. Но когда станет вопрос производительности — лучше иметь способ отфильтровать данные до передачи в поток вывода.
                                                                • 0

                                                                  Выше упоминали уже, если Вас напрягают такие вопросы — Вам надо смотреть в сторону OS Plan9 или OS Inferno. Там с оригинальной философией UNIX всё хорошо. Ссылки в тему (про cat, а не ls, но суть примерно та же):
                                                                  http://harmful.cat-v.org/cat-v/
                                                                  https://github.com/pete/cats

                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                  Самое читаемое