Комментарии 116
Объектные шеллы типа powershell?
Определить формат выдачи.
Отдельная команда: ls | ft — форматировать как таблица
Изменить порядок файлов. −r для списка в обратном порядке; −t для списка файлов по времени последнего изменения.
ls | sort -descending
Включить или исключить определённые файлы. −a включает в список файлы, скрытые по умолчанию; −R показывает рекурсивный список файлов в подкаталогах текущего каталога.
Тут уж сама команда ls
Там можно сократить до подстроки уникально идентифицирующий параметр
Get-ChildItem -Recurse эквивалентно ls -r
Насколько я знаю, что общепавершельное сокращение. Моджно ввести первые буквы параметра пока префикс однозначно его не определит:
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 чтобы попробовать
Если все реализовывать в виде последовательности фильтров, то на больших файловых системах, где в каталогах бывает > 10^6 файлов будет невозможно получить необходимый функционал либо он потребует неадекватного количества ресурсов.
— Кроме того непонятен наезд на иерархичность файловых систем. В UNIX это вообще-то многосвязный граф (с возможностью использования механизмов предотвращения зацикливания при рекурсивном сканировании), а вовсе не строгая иерархия.
Если все реализовывать в виде последовательности фильтров, то на больших файловых системах, где в каталогах бывает > 10^6 файлов будет невозможно получить необходимый функционал либо он потребует неадекватного количества ресурсов.
Почему?
ls -l | awk '{print $9}'
то у вас сначала выведется 9 колонок с метаданными и только потом вы возьмете нужную колонку (3-4% от начальных данных). А можно испольвать
ls -1
который сразу выведет только имя. Это если передавать данные, а не абстрактные объекты или лямбды
Эффективнее иметь умный генератор данных и тупой обработчик, нежели тупой генератор объектов и умный обработчик.
ls | sort -descending
Все бы ничего, но иногда обратная сортировка нужна не по первому полю, а, например, по размеру, а в именах файлов встречаются пробелы, и мы снова приходим либо к кавычкам-ескейпам, либо к более структурированному потоку данных, как в powershell. Грустно. Еще грустнее, если вспомнить, что в acsii есть символы «разделитель полей», «разделитель записей».
Смысл больше в том чтобы их спрятать с глаз долой, а не скрыть в них что либо.
Почему вы решили, что в powershell команда ls по умолчанию выводит скрытые файлы?..
" Включить или исключить определённые файлы. −a включает в список файлы, скрытые по умолчанию; −R показывает рекурсивный список файлов в подкаталогах текущего каталога.
Тут уж сама команда ls"
Отсюда мой вывод что команда ls выводит скрытые файлы.
Где именно тут написано, что команда ls в powershell выводит скрытые файлы по умолчанию?
Тут написано всего лишь, что управление выводом скрытых файлов или рекурсивностью обхода — это ответственность самой команды ls. По умолчанию и то, и другое выключено.
Как автор написал так я его и понял. Что именно имел ввиду автор знает он сам.
Не вижу проблем в соответсвии ls
с идеологией unix, ведь все что делает ls — это:
> List information about the FILEs (the current directory by default)
Ну да, она так же позволяет выбрать формат вывода в удобной форме, но это необходимый шаг т.к. вывод происходит в виде обычного ASCII-текста а не объектов, это имеет свои плюсы и минусы конечно, но сути это не меняет, ls
только выводит информацию о файлах в желаемом формате.
Кстати если вас так вдохновляет идеология Unix, возможно вам будет интересно почитать про Plan 9
Спасибо за статью!
Эдак про любую раздутую утилиту можно сказать "не вижу проблем с идеологией unix, да у нее 100500 фич — но это необходимый шаг т.к. мы пишем под винду где нет (не было) хорошего шелла для интеграции разных утилит".
Видимо вы меня не так поняли,
Я рассказал о том, что ls
не выполняет никаких дополонительных фич, что вполне вписывается в идеологию unix. Она не копирует файлы, не меняет их атрибуты и т.п.
А все ключи здесь нужны только для настройки вывода, т.е. с помощью ключей вы задаете как имено вы хотите что бы она исполнила свою основную функцию.
Синдрома nero здесь не наблюдается :)
Почему вы считаете, что копирование файлов — это лишняя функция, а форматирование данных — нужная?
Потому что это часть основной функции программы, ls — это в первую очередь инструмент для пользователя, поэтому здесь так много настроек форматирования.
В случае если вам не нужен форматированный вывод вы можете воспользоваться ls -1
и другими более подходящими для этого инструментами, например find
.
Потому что это часть основной функции программы
Поучему?
В PowerShell
Формат в виде таблички ft формат в виде html Out-Html открыть grid view c сортировкой и фильтором — ogv.
Это все надо запихивать в ls?
и в ps?
Вот так вывести процессы в виде таблички сгруппированной по имени
ps | sort Name | ft -GroupBy Name
Вот так вывести службы сгруппированные по статусу
gsv sql | sort Status | ft -GroupBy Status
Надо учить для каждой командой свои особые флаги?
Поучему?
Потому что в PowerShell вы оперируете объектами, а ls
как и другие unix-tools на выходе дает обычный текст.
В этом и разница двух подходов.
В первом случае — это удобство и вся мощь работы с объектами.
Во втором случае — большая гибкость, и полная независимость от среды выполнения.
Вот так вывести службы сгруппированные по статусу
gsv sql | sort Status | ft -GroupBy Status
Это безусловно прекрасно, но к сожалению это работает только в пределах среды PowerShell, хотя не спорю, во многих случаях этого бывает достаточно.
Но например с помощью nix'вых sort
, sed
и awk
я могу творить просто невероятные вещи. Я могу удаленно выполнять команды в любом! шеле, получать и обрабатывать данные от них точно так же как от любых других програм, и при этом они не должны быть частью шела.
В этом вся прелесть работы с текстом. В этом подходе есть конечно и минусы, куда же без них.
Но так уж завелось, что в unix каждая программа написана отдельным разработчиком. Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.
Надо учить для каждой командой свои особые флаги?
К сожалению да.
Но например с помощью nix'вых sort, sed и awk я могу творить просто невероятные вещи. Я могу удаленно выполнять команды в любом! шеле, получать и обрабатывать данные от них точно так же как от любых других програм, и при этом они не должны быть частью шела.
В принципе текстовые потоки совершенно так же обрабатываются этими командамию. То есть можно из cmd запустит powershell sort и он отсортирует поток строк.
Коммандлеты представляют собой отдельные компоненты — они не обязаны быть частью шелла — вы можете написать свой шелл с другим синтаксисом, главное использовать те же интерфейсы — концептуально то же самое.
Вот PowerShell type provider для F# позволяет использовать команды powershell в F# с синтаrсисом F#
Только текстовый шелл использует самый простой интерфейс — просто поток. И самый бедный. Вы можете привести бедный интерфейс к богатому и наоборот.
В этом вся прелесть работы с текстом. В этом подходе есть конечно и минусы, куда же без них.
Но так уж завелось, что в unix каждая программа написана отдельным разработчиком. Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.
Так же в винде есть независимые поставщики командлетов — CISCO например
Bash со всеми unix-tools связывает весь этот зоопарк просто на отлично.
Надо учить для каждой командой свои особые флаги?
К сожалению да.
Это значит что не на отлично, а что просто там другое соотношение компромиссов между простотой использования и простотой внутренного устройства, более привычный вам
1) правильные имена
2) не более 3-переменных в классе
Ну это я так, абстрактно посмотрел…
И это по моему немаловажная ценность консоли, она может быть не идеальна, но ты изучаешь её один раз и потом не имеешь проблем с ней, а просто берешь и работаешь.
Мой прадед пользовался счетами.
Мой дед пользовался счетами.
Мой отец пользовался счетами.
Зачем нам изобретать калькуляторы и компьютеры, если есть проверенные веками счеты?
Берешь их, изучаешь один раз и просто берешь и работаешь…
Нужна тебе команда выводящая в каком-то особенном виде? Что мешает написать один раз скрипт ListInMyCoolFormat на основе того же ls и пользоваться им? Нет, блин, надо целую философию развести на пустом месте…
И никому в голову не пришло что давайте сделаем команду ListDirectoryContents так же явно понятней
Вообще-то пришло, в большинстве командных интерфейсов используются длинные параметры с автодополнением: Cisco (и многочисленные клоны), NetApp, IBM TSM, PoSH.
Но в мане гентыы допустим сказано:
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 с нужным ключем.
И всё ещё неправильно. В имени могут быть пробелы и даже переносы строк. Правильно — переписать всё на Си, что в ls и сделали.
Нет ничего удобнее, чем вбить ls -lrt
и посмотреть последние изменения в каталоге. А ещё никто не мешает сделать удобные для запоминания алиасы:
alias ListFilesSortedByLastModificationTime='ls -lrt'
Не сочтите за грубость, но это тоже не будет работать:)
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, настоятельно рекомендуется к прочтению, и это тоже.
У некоторых людей такой юниксвейный подход к проектированию интерфейсов вызывает глубокую депрессию.
собственно сортировка и управление порядком.
Сортировка и есть управление порядком
4. где-то во всем этом теряется информация о формате вывода: ls ею уже не управляет, а остальные программы работают с потоком записей, форматирование уже не их задача, так что нужно указать еще один компонент команды, что-то вроде такого:
ls | sort --field=modification-time | reverse | print --field=name
Powershell:
ls | sort LastWriteTime -d
- sort занимается порядком, в том числе и по убыванию
- формат вывода определяется конфигом на основании типа объекта
- если зхочется выбрать одно поле можно воспользоваться select или % (foreach)
Конфиг может влиять на записанные скрипты если они переводят объекты в строки и не казывают явно как.
Согласен, что reverse бывает и другой но это концептуально опять не требует потоков данных. Они как в LINQ могут строить дерево выражений и отдавать провайдеру файловой системы, например. Без дополнительной сортировки
Любую задачу управления порядком можно свести к сортировке.
Тем не менее, в конкретном случае разворота последовательности этот самый разворот прекрасно вписывается в операцию сортировки как философски, так и практически.
Боюсь, автор недопонял философию unix: "Делайте что-то одно, но делайте это хорошо".
ls делает одно дело — выводит список файлов. И делает это настолько хорошо, что мне больше ничего не нужно, когда я хочу посмотреть список файлов.
Писать "ls -la" куда удобнее, чем ls | sort | grep | sed | awk ...
ls кажется раздутой, потому что она действительно раздутая.
Она может показаться раздутой для программиста, но для пользователя она очень проста и лаконична. Философия unix, насколько я могу судить, старается поворачивать программы и интерфейсы лицом к пользователю. Пусть даже программисту придется постараться для этого.
Но почему не написать более простую альтернативу ls — функцию, которая берёт произвольный каталог, или рабочий каталог по умолчанию, и возвращает список файлов из него, не обращая внимания на флаги?
Ну так понятно — раз так в 500 удобнее работать с буфером в своей памяти, в котром лежать данные типа «запись», структура и последовательной полей которой известна, чем читать строку символов, ее парсить в ту же запись — удобное внутреннее представление, чтобы отфильтровать. А потом окажется, что в новой версии легковесная ls выдает больше или меньше полей, или меняет последовательность, и старые программы-фильтры сдохнут. Или придется добавлять флаг вида «дай новый более удобный вывод», что опять приводит к раздутию.
А потом, как всегда внезапно, придет осознание, что для наиболее частого сценария надо вместо одной команды запускать конвейером две, причем вторая будет просто тупо брать первое поле — имя файла, выкидывая остальное, делая сериализацию/десериализацию данных пустой тратой процессорного времени. Альтернатива — опять же добавить флагов вида «дай краткую инфу-дай полную инфу».
Т.е. как ни крути, раздутие будет. Философия «сложим все из кирпичиков» хороша, но не универсальна. Как обычно — любая догма, как «запихать все в одну программу», так и «всегда разбивать на кирпичи», проигрывает взвешенному подходу.
Представьте язык программирования, в котором каждая функция принимает в точности один аргумент (строку) и возвращает в точности один результат (другую строку).
Ой, посмотрите — такой язык существует, и он называется шелл.
Вообще функции в sh получают произвольное количество аргументов и позволяют вернуть только код возврата (одно число).
Программы не «принимают аргументы» и не «возвращают значения», они читают символы из stdin и печатают символы в stdout!
Что-то в мане по exec написано, что можно аргументы массивчиком передавать, а ещё и массивчик с environment variables. Та и в мане по exit статус тоже присутствует. Что вообще имелось ввиду под таким громким высказываением?
Статья — какое-то непотребство дилетанта-графомана. А вот за комментарии вам, господа, огромное спасибо! Полезной и интересной информации великое множество.
А что в винде так принципиально и несовместимо поменялось со времен NT? Та же эволюция
Дык это все ж друг друга не отменяет. Часть вообще на разных уровнях абстракции (COM <- ActiveX <- OLE). И все это поддерживается с момента изобретения. Какая революция?
Это одна из проблем всего этого вороха технологий.
То есть надо не поддерживать обратную совместимость?
Каждый раз настоятельно рекомендуют использовать последнюю выдуманную ими фигатень. И эта фигатень кардинально отличается от предыдущей, а пишущие на старой фигатени чувствуют семя ретроградами.
То есть получается что проблемы чисто эмоционального характера — чувство себя ретроградом?
Мне кажется, что вы не очень разбираетесь в аббревиатурах:
DDE это часть WInAPI
MFC — бибиотека поверх winapi для C++
COM — объектно-компонентная технология построения приложений
ActiveX — COM объекты с поддержкой автоматической регистрации
OLE — набор COM интерефейсов для встраивания компонентов друг в друга
.NET — единственная отдельностоящая технология здесь но тесно связанная с остальными
Надо быть последовательным, и развивать старые интерфейсы, а не забрасывать их и делать новые.
Как я уже написал, старые интерфейсы не развиваются.
Что именно не развивается из перечисленного?
Да я вообще утрировали, подгоняя под зарисовку «Фатальный недостаток», которая прекрасно показывает путь развития Windows.
Не получилось ли так, что утрирование иказило картину?
Как вы себе представляете "развитие" DDE-то? Куда ей там дальше развиваться?
Говорить, что OLE заменили на ActiveX — тоже некорректно. Это две версии одной и той же технологии.
Прекращение же поддержки ActiveX в браузере было давно ожидаемым шагом. Просто потому что эта технология слишком небезопасна и платформо-зависима для веба.
Еще можно посмотреть, что случилось в других браузерах за это время. Кто поддерживает NPAPI например
Не уходите от вопроса. В каком направлении могла развиваться эта технология?
DDE — это технология, основанная на пересылке оконных сообщений между процессами.
OLE — это технология, основанная на объектном подходе и, в основном, внутрипроцессном взаимодействии.
Они отличаются как сокеты и С++ — это ж совершенно разные вещи!
Хотите работать со структурированными данными? Возьмите любой язык программирования и работайте напрямую с сисколами, вызовами функций библиотек и тд. В реальности даже не придется доходить до таких крайностей и можно просто запустить интерпретатор python/php/ruby/etc в интерактивном режиме, будет как раз тот структурированный вывод, работа с объектами и все остальное, что вы так хотите. Попробуйте, если сможете проработать в таком шеле неделю пишите статью на хабре о уникальном опыте, но вероятнее всего такая работа надоест через 10 минут, т.к. по сравнению с башем и coreutils занимает гораздо больше времени при сомнительных плюсах.
Напишите, оценим. Критикуя — предлагай. Должно быть достаточно тривиально реализовать это все. Начните с написания своего шелла, (простой интерпретатор неделя работы, можно взять луа или что-то подобное) затем запилить протокол обмена данными, думаю максимально эффективно будет взять простой джейсон на каждый объект.
ls называется ls по той же самой причине, по которой её флаги представляют собой зашифрованные руны из одного символа вместо осмысленных слов или, не дай бог, целых фраз
ls
называется ls
из соображений эргономики, чтобы можно было быстро получить список файлов в директории нажатием трёх клавиш, а не путём написания сочинения на тему "dear computer, please print the list of the files in the current directory for me".
Выше упоминали уже, если Вас напрягают такие вопросы — Вам надо смотреть в сторону OS Plan9 или OS Inferno. Там с оригинальной философией UNIX всё хорошо. Ссылки в тему (про cat, а не ls, но суть примерно та же):
http://harmful.cat-v.org/cat-v/
https://github.com/pete/cats
Настоящий Unix — не есть приемлемый Unix