Всем привет!
После вчерашнего поста о замене штатного ls другими штатными (или не очень) утилитами, я просто не мог пройти мимо комментов, особенно учитывая то что пост взлетел на вершины хит-парадов и за сутки его прочитало 18k, с хвостиком человек. Хабровчане подарили миру много новых способов избавиться от ls. Я их все (но это не точно) проверил, некоторые «причесал», что бы они соответствовали условиям задачи, и хочу поделиться с вами. Наслаждайтесь!
1. dir
Да, чОрт возьми. У меня она совершенно вылетела из головы. И хотя она совсем другая чем в DOS, Windows и даже в OS/2, свои функции выполняет исправно!
Про неё мне напомнили eumorozov и cru5ader
dir -aA ~
2. printf
Каюсь. zsh меня испортил и я считал, что print это такая утилита — лайт версия echo, а оказалось что это просто потроха самого zsh. Зато iig показал мастер-класс использования printf
printf "%s\n" ~/* ~/.*
3. echo
Да, это снова он… работающий через автоматический autocompletion. За такое благодарим SlavniyTeo
echo -e 'echo \t\ty\b\b\b\b\b\b\b' | bash -i
echo -e 'echo \t\ty\b\b\b\b\b\b\b' | sh -i
А вот пользователям zsh не повезло, хотя может быть если настроить?
3. vim
cru5ader напомнил, что в vim есть собственный файловый браузер, а так как vim есть везде (ну почти. На манджаро стоит обычный vi и с ним такой фокус не пройдёт) то почему бы этим не воспользоваться?
vim ~
4. rm
Да! Ваши глаза вас не обманывают. То что является основой знаменитого патча Бармина, которым пугают начинающих юниксоидов, мы будем использовать исключительно в мирных целях. Спасибо POPSuL
yes "n" | rm -i $HOME/* $HOME/.* 2>&1|grep -o "$HOME[^']*"
И Cheater
(echo y; yes n) | rm -ir ~ 2>&1 | sed -E -e "s/(rm:[^']+)|\?//g"
5. rsync
А собственно, почему-бы и не да? Благодарим за это 027
rsync --list-only ~/
6. grep
Грепом можно не только проверять e-mail на валидность, но и выгреПать файлы. kashtan404 и
KorDen32 показали что и это ему под силу (пофикшено на более правильный вариант).
grep -l '.*' ~/* ~/.* 2>/dev/null || grep -L '.*' ~/* ~/.* 2>/dev/null
7. file
Хотите понять что за файлы лежат в вашем хомяке? А может просто вывести их список? 027 и POPSuL доказали что и это ему под силу.
file ~/* ~/.*
8. stat
Статус файла или целой файловой системы? Не только! Способов нетрадиционного приготовления stat существует как минимум три. Одно даже от меня.
stat ~/* ~/.*|grep "/home"|awk '{print $2}'
Другое от polar_yogi
stat -c "%A %G:%U %s %x %n" * \.*
И третье от iig
stat *|awk '/File:/{print $2}'
9. head
Artyushov — голова! Показал как надо использовать head!
head -n 0 -v ~/* ~/.*|awk '{print $2}'
10. getfacl
Ключевая буква в названии этой утилиты — «f» и Zoro это доказал!
getfacl ~/* ~/.* | grep "# file" | awk '{print $3}'
11. git
Да, даже Git камрад tork заставил работать на хомяка!
git init ~/ ; curr=`pwd`; cd ~ ; git status; rm -rf .git; cd $curr ; curr=''
12. cat
Все любят котиков. Но самые крутые у пользователей BSD систем! К сожалению в линуксе котики не той породы. :-( Uzix похвастался своим cat-ом.
cat ~ |strings |xargs -IX sh -c 'test -e X && echo X'
13. lsattr
lsattr это
lsattr ~/* ~/.* 2>&1 | grep -Po '/.*'
Эпилог
На чёртовой дюжине я пожалуй остановлюсь, но интересующиеся могут заглянуть в комменты оригинального поста и насладиться, так как «за бортом» остались однострочники на perl, ruby, python, php и даже С++.
Комментарии (50)
DarthVictor
12.09.2019 11:41А еще есть exa, она не стандартная, зато с подсветкой.
eumorozov
12.09.2019 11:51Кстати, я так и не понял в чем прелесть. Одно время использовал
alias ls=exa
, но потом перестал, т.к. разницы сls --color -F
почти и нет.
Какие-то преимущества у exa наверное и есть, но для человека, проработавшего в bash десятилетями, они настолько незначительны, что игра не стоит свеч, по-моему.
А если относительно темы статьи, то это похоже на читерство. И exa вряд ли распространенный инструмент.
amarao
12.09.2019 11:51О да, больше glob'а. Это так неожиданно. /сарказм
edo1h
12.09.2019 13:02вот-вот, странно читать «с помощью XXX», а всю работу выполняет шелл, развернувший *.
упомянуть об этом способе нужно, конечно, но не преподносить его как 20 разных способов же.POPSuL
12.09.2019 13:13В некоторых способах можно и без него обойтись, даже в моем варианте с rm. Добавить флаг
-r
и добавить один символ вgrep
. Для меня это очевидная альтернатива, но я не написал этот вариант именно в таком исполнении, потому что он может выполняться бесконечно долго.edo1h
12.09.2019 13:22В некоторых способах можно и без него обойтись
там, где можно обойтись (и обошлись) — там это отдельный способ. где используется * — один.
не написали же миллион способов с find, хотя все способы с * можно переписать на find.
SlavniyTeo
12.09.2019 13:12Не знаю, как так получилось, но в первой статье нет моего второго комментария (забыл нажать кнопку "Опубликовать?").
Просто на всякий случай напоминаю условия задачи:
Выведите список файлов в домашней директории максимально возможным количеством способов, без использования ls или его алиасов(1 способ — 1 балл)
Варианты решения:
mc $HOME
nautilus $HOME
gopen $HOME
— можно даже так- ...
- ну не буду же я перечислять все файловые менеджеры
POPSuL
12.09.2019 13:15Такие себе решения, особенно когда у тебя есть доступ только по ssh, к какой-то виртуалке, в которой злоумышленники похерели базовые утилиты (ну, это единственное практическое применение всем предложеным вариантам).
SlavniyTeo
12.09.2019 13:22Ну все, что я могу добавить для случая с похереными базовыми утилитами по ssh:
chromium-browser "file://$HOME"
Вообще, я не зря привел условие задачи в своем комментарии.
SlavniyTeo
12.09.2019 13:28Увидел, что в первой статье такой вариант указали за пол часа до меня. Версия с хромиумом в headless режиме очень даже ничего
027
12.09.2019 13:50А я как-то ковырялся по телнету в роутере, где ls попросту отсутствовал в бизибоксе.
POPSuL
12.09.2019 14:30Да, и такое бывает. А еще бывает когда есть ls, но нет mv/cat/cp/etc… Нужна еще серия статей для поиска альтернатив другим утилитам! :)
3vi1_0n3
12.09.2019 22:55+2Типа такого?
https://m.habr.com/en/post/145073/
Там комментарии тоже огоньPOPSuL
13.09.2019 01:02Ну вроде того, но хотелось бы больше извращений как в этой статье :)
Но статья отличная, спасибо!
Oxyd Автор
13.09.2019 04:22Ох! Какая знатная замена трейсруту! Спасибо за ссылку.
027
13.09.2019 19:51Знатная замена трейсруту — mtr (my traceroute)
А тот наколенный скрипт не показывает хопы, которые не отвечают.
Clasen01
12.09.2019 17:09теперь нужны бенчмарки для всех команд, какая из них эффективнее справляется с задачей) (быстрее работает с большим количеством папок)
027
12.09.2019 18:01теперь нужны бенчмарки
Прошелся по примерам в первой статье.
Тестовая дира — плоский каталог, около 15 тыщ файлов.
Делать лень, взял готовый.
$ ll | wc -l 14881
Выхлоп везде поскипан, естессно.
Бенчим1)
time for i in ./* ./.* ; do echo $i ; done ... real 0m0,263s user 0m0,189s sys 0m0,051s
time echo ./* ./.* ... real 0m0,111s user 0m0,070s sys 0m0,008s
2)
(пришлось устанавливать, искаропка подвела)
time tree -aiL 1 ... real 0m0,226s user 0m0,127s sys 0m0,064s
3)
time find . -maxdepth 1 -mindepth 1 ... real 0m0,117s user 0m0,039s sys 0m0,034s
4)
time du -ad 1 . ... real 0m0,164s user 0m0,027s sys 0m0,076s
5)
time tar -cvf /dev/null --no-recursion ./* ./.* 2>null ... real 0m0,265s user 0m0,121s sys 0m0,111s
6)
time perl -e 'use feature "say"; opendir my $dh, "." or die "Could not open . for reading: $!\n"; while (my $thing = readdir $dh) { say $thing; };' ... real 0m0,112s user 0m0,038s sys 0m0,029s
7)
time echo -e "import os\nfor i in os.listdir('.'): print(i)" | python ... real 0m0,120s user 0m0,032s sys 0m0,039s
Мой вариант:
time rsync --list-only ./ ... real 0m0,210s user 0m0,094s sys 0m0,091s
Сама ls:
time ls ... real 0m0,223s user 0m0,103s sys 0m0,043s
Sly_tom_cat
12.09.2019 19:24Всего чего угодно ожидал но не того что питон и перл порвут ls…
027
12.09.2019 19:31+1На прогретом кэше — почему нет? Чтением каталога все равно сишные программы занимаются, интерпретаторы чисто обертка. Баш, кстати, тоже интерпретатор.
А ls, что ls… оно по умолчанию, еще и сортирует. А без сортировки, вот:
time ls -f ... real 0m0,114s user 0m0,030s sys 0m0,026s
И кто знает, что там набенчится, если перл заставить сорт… Черт! Вспомнился чудный перл с баша:
* Daemon потыкал палочкой в wd
яя
а чиво станет с перлом, если в хеш загнать 2 гига данных и заставить перл его сортировать?
будет сортировать
неожиданно
Aldrog
13.09.2019 09:38Мне кажется или в вариантах с глобами правильнее делать
time bash -c '...'
, чтобы время разворачивания глобов тоже учитывалось?027
13.09.2019 20:07Нет, разброс от запуска к запуску больше, чем разница между вариантами с
bash -c
и без.
Правильнее делать многократные измерения с усреднением, но мне лень. :)
Aldrog
14.09.2019 14:18У меня так (time из zsh):
Заголовок спойлера1) Запускал через bash, потому что zsh отказывается замерять время работы echo напрямую
bash -c 'for i in ./* ./.* ; do echo $i ; done' 0.01s user 0.00s system 97% cpu 0.011 total
bash -c 'echo ./* ./.*' 0.01s user 0.00s system 96% cpu 0.009 total
2) Тоже пришлось устанавливать
tree -aiL 1 0.01s user 0.00s system 96% cpu 0.010 total
3)
find . -maxdepth 1 -mindepth 1 0.01s user 0.00s system 95% cpu 0.008 total
4) Ожидаемо сильно страдает от большого числа вложенных директорий
du -ad 1 . 1.46s user 17.90s system 6% cpu 4:38.79 total
5)
tar -cvf /dev/null --no-recursion ./* ./.* 2> null 0.12s user 0.00s system 90% cpu 0.134 total
6)
perl -e 0.01s user 0.00s system 23% cpu 0.024 total
7)
python 0.03s user 0.01s system 90% cpu 0.034 total
rsync
rsync --list-only ./ 0.01s user 0.01s system 82% cpu 0.016 total
ls
ls --color=auto 0.01s user 0.01s system 5% cpu 0.259 total
ls --color=no 0.01s user 0.00s system 95% cpu 0.009 total
drbald
12.09.2019 20:38Удивительно, что всё еще нет картинки про буханку хлеба и троллейбус.
027
12.09.2019 20:46И действительно, как это ни один мимокрокодил, ничего тут не понявший, не набижал с буханкою наперевес?.. (снедаемый эффектом Даннинга-Крюгера)
Oxyd Автор
13.09.2019 04:32+2А зачем? Это же развлечение чисто Just for fun. Ну, как brainfuck какой-нибудь.
027
Я там поправочку вносил, чтобы мусора не оставалось:
Oxyd Автор
Поправил и добавил.
027
Это да, я бездумно добавил из исходного примера с просмотром текущей директории.
А вот так попроще будет:
Кстати, будет досадно, если в исследуемом каталоге .git уже был. :)
miraage
Можно завернуть в subshell, чтобы cd обратно не делать.
027
Кстати, да, я вечно про него забываю.
Oxyd Автор
Всё хорошо с Git, кроме одного косяка…
"\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\321\213/"
"\320\227\320\260\320\263\321\200\321\203\320\267\320\272\320\270/"
"\320\230\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217/"
"\320\234\321\203\320\267\321\213\320\272\320\260/"
"\320\240\320\260\320\261\320\276\321\207\320\270\320\271 \321\201\321\202\320\276\320\273/"
Это собственно каталоги с русскими именами. Шаблоны, Рабочий стол, вот это вот всё. ;-)
027
Пользуйтесь на здоровье :)