- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
#!/bin/bash
for i in *.root
do
if [ ! -e "$i" ] # Проверка наличия файла.
then
echo "Файл $i не найден."; echo
continue
fi
# ... etc ...
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−134
#!/bin/bash
for i in *.root
do
if [ ! -e "$i" ] # Проверка наличия файла.
then
echo "Файл $i не найден."; echo
continue
fi
# ... etc ...
Не, ну а вдруг
unu-foja 12.09.2013 09:35 # +4
Вообще-то ваш любимый баш в случае отсутствия .root, занесет в i строку "*.root" так то!
bormand 12.09.2013 09:54 # +10
Скрипт искал рядом с собой tgz файлы, создавал папку с именем, полученным отрезанием расширения tgz, распаковывал туда архив, что-то там внутри обрабатывал, и удалял папку и сам архив. Все было бы красиво и безоблачно, если бы я не запустил скрипт вхолостую, без tgz файлов...
for засунул в переменную *.tgz, после отрезания расширения получилась просто *, и скрипт, с достоинством настоящего самурая, вынес свой конфиг, свой лог и самого себя :)
unu-foja 12.09.2013 10:28 # 0
Эпично... Но подозреваю отсутствие двойных кавычек, некомильфо.
Впрочем, shell вообще часто радует, особенно если захотеть написать с намеком на портабельность (тот же echo -e в убунте).
Не так давно узнал, что shell-ы удаляют не только последний перевод строки, а все финальные. Забавно было получать realpath от file=$'smth\n' .
<оффтоп>Кстати кто-нибудь в курсе чем мотивируют, что glob без совпадений не возвращает пустую строку? (как всякие nullglob в bash/zsh)
bormand 12.09.2013 10:49 # +2
Ну естественно :) Пока гром не грянет, админ кавычки не поюзает.
> тот же echo -e в убунте
А что с ним не так?
> glob без совпадений не возвращает пустую строку
Ну например запускаем cat *.dat. Сейчас он говорит cat: "*.dat: No such file or directory". А с nullglob'ом будет "зависать" (читать с stdin'а). Сменили шило на мыло...
unu-foja 12.09.2013 19:10 # 0
Случайно как-то, уже не помню, по-хорошему переименовать, конечно, надо. А тут стало интересно. (А вообще частенько из *.zip кириллица валится всякая хрень.)
Внезапно, проще так: file=$'smth\n'; touch "$file" ($'\..' - башизм)
> А что с ним не так?
В dash/echo нет такой опции :) (по-крайней мере когда-то не было). http://pubs.opengroup.org/onlinepubs/009696799/utilities/echo.html :
It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted. The printf utility can be used portably..
(/bin/echo -е портируем в пределах gnu/coreutils, а вот встроенный - в пределах интерпретатора)
> Сменили шило на мыло...
Точно, просто почему-то я сидел на двух стульях: null - для внутренних, "" - для внешних. Но у "шила" еще один момент: литеральный "*.root" может существовать - в любом случае нужно фс дергать.
bormand 12.09.2013 19:25 # 0
- вообще прерывать исполнение при пустом глобе. И выводить "bash: *.dat: No such file or directory", даже не запуская саму программу.
- а в for'е пусть nullglob будет всегда включен. Это, вроде как, единственное место, где допустимо и очень желательно раскрытие в ничто.
unu-foja 12.09.2013 19:40 # 0
Тоже не айс: rm *.o *.old (а какие действительно есть - сразу не известно)
> желательно раскрытие в ничто
Ну конкретно для баша в массивах бы еще не помешало: arr=(*.root)
bormand 12.09.2013 20:03 # +1
3.14159265 12.09.2013 20:24 # +1
Ну по крайней мере логично написать один раз и сохранить ряд (пачку) инструкций в файл, и выполнять их.
Потом раз, стало много копипаста - нужен цикл.
Потом хочу небольшое ветвление, а то неудобно!
Потом эх! вот бы еще аргументы передавать.
Так тихо получили кашу из топораязык.
bormand 12.09.2013 20:33 # +1
Посмотри в моем комменте ниже сниппет про файл с именем -rf. Вот отличный пример того, к чему приводит "удобство".
3.14159265 12.09.2013 21:08 # +1
Кстати примерно тоже и в крестах. Отдельно от всего фича полезная, а в совокупности превращает язык в минное поле.
>ниже сниппет про файл с именем -rf
Видел. Это прекрасно.
kegdan 13.09.2013 05:30 # −1
guest 12.09.2013 23:47 # −7
[email protected] (Спросить Тараса)
bormand 12.09.2013 22:38 # +2
Потому что они, как правило, очень хорошо удовлетворяют текущие потребности большинства (за счет неминуемого пиздеца в будущем, которое далеко и никого не волнует, пока не коснется их лично).
Если отойти от программирования, и взглянуть на тот же макдональдс, то мы увидим ту самую "неудачную идею с поразительной жизнеспособностью": толпы людей жрут фастфуд не думая о своем ожирении, ибо удобно ;)
anonimb84a2f6fd141 12.09.2013 23:10 # −1
Относительно баша - его можно рассматривать не как хуевую версию перла/фитона, а как хорошую - бата.
bormand 12.09.2013 23:47 # 0
Если баш юзать не для всего подряд, то все норм ;)
> как хорошую - бата.
Ну да, как пакетный файл для примитивных задач баш хорош.
> не как хуевую версию перла/фитона
А вот для более серьезного скриптинга, когда надо прочитать какой-то файл, бегать в цикле по директориям, юзать регулярки, баш становится очень неудобным. Если не знать и не учитывать все неожиданности и подвохи - код будет дырявым бажным говном. Если учитывать - длинной некрасивой портянкой намотанной на костыли, которая на обычных языках была бы короче и наглядней.
И да, баш сложен. Изучение всех этих тонкостей всяко занимает больше времени, чем изучение того же питона, который, за исключением пары мест, туп как пробка и логичен.
В общем у всего есть своя область. И у баша это написание небольших скриптов, не требующих особой надежности, на скорую руку.
Stealth 15.09.2013 17:26 # 0
Та ну нах … даже поддержка функций есть
bormand 15.09.2013 17:40 # +1
Из которых даже можно вернуть результат (через глобальную переменную).
bormand 12.09.2013 20:24 # +4
bormand 12.09.2013 20:53 # +5
1024-- 12.09.2013 21:07 # −1
(т.е. если неюниксоид смог удалить печаль, то юниксоиду бояться нечего)
bormand 12.09.2013 21:12 # +2
Ну это потому что видел в первой строке, как создают файл. Без этого батхертов было бы больше. Как минимум пришлось бы вспоминать альтернативные способы получения списка файлов, или тупо запустить mc ;)
1024-- 12.09.2013 21:16 # 0
Я сначала выполнил ls без параметров, чтобы убедиться, что у меня создан файл -rf или --help, чтобы приступить к написанию "ls *". Всё работало без альтернативных способов.
bormand 12.09.2013 21:48 # +4
bormand 12.09.2013 21:56 # +2
1024-- 12.09.2013 22:24 # 0
ООП + утиная типизация в ФС. Вместе с данными (1.txt, xxx.log, ...) хранятся методы (-что-то). Для некоторых каталогов перепределены методы ls, rm и т.д.
bormand 12.09.2013 22:27 # 0
Не получится. Все эти опции в кучу смешаются, и команды начнут выдавать ошибки о неизвестных опциях...
А насчет переопределения методов для некоторых каталогов - fuse вам в руки.
anonimb84a2f6fd141 12.09.2013 23:12 # −2
// не прыщеблядь
bormand 12.09.2013 23:38 # +1
Звездочка раскрывается в список всех файлов, находящихся в каталоге. В результате имя файла "--checkpoint-action..." (да, в *nix'ах в именах файлов можно юзать любые символы помимо '\0' и '/') попадает в командную строку tar'а. Но т.к. автор быдлобекапилки не указал опцию -- чтобы tar понял, что дальше аргументов нет, tar парсит --checkpoint-action как опцию. Данная опция заставляет его выполнять некое действие каждый блок (10кб), в нашем случае это действие - произвольный код из evil.sh.
Вот как-то так.
anonimb84a2f6fd141 15.09.2013 03:44 # −1
Vindicar 13.09.2013 09:08 # 0
Честно говоря, подозреваю что в данном конкретном случае виндовый подход лучше. Хотя бы вот таких факапов не возникает.
anonimb84a2f6fd141 15.09.2013 03:40 # −1
Еще лучше было бы если бы список файлов передавался каким-то массивом.
anonimb84a2f6fd141 15.09.2013 03:39 # −1
А вообще - достойно отдельного говнокода.
govnomonad 13.09.2013 05:04 # +1
govnomonad 13.09.2013 05:06 # 0
bormand 13.09.2013 05:26 # +2
Само собой есть. Но сколько человек его юзает? :)
Как я и писал выше - кодить на баше просто и красиво ровно до тех пор, пока не требуется надежность и поддерживаемость. Иначе это геморрой с изучением тонкостей каждой команды и каждой синтаксической конструкции. Даже для простейших конструкций типа "для каждого файла в каталоге" или "заменить че-то на че-то регуляркой" нужно знать правильные идиомы.
bormand 13.09.2013 05:43 # +2
bormand 13.09.2013 05:48 # +1
Ну и где же эта хваленые простота и удобство баша? :)
guest 13.09.2013 07:08 # 0
Вот вам "портабл":
find ! -name . -prune -name '*.txt' -printf '%f\n'
А в вашем питоне glob пропустит .якобы-так-и-задумано.txt
bormand 13.09.2013 07:44 # +1
Который ломает к хуям все остальные команды с глоббингом, и нужно включать и выключать его перед каждым фором.
> А в вашем питоне glob пропустит .якобы-так-и-задумано.txt
Вы так говорите, как-будто башевский глоббинг их не пропускает ;)
Если надо хиддены - есть os.listdir + fnmatch, о которых, даже упоминается в доке по glob. Но часто хиддены и не надо обрабатывать, они же неспроста скрыты.
> find ! -name . -prune -name '*.txt' -printf '%f\n'
Ахуеть интуитивный способ.
Я же не говорю, что в шелл скриптах невозможно что-то реализовать. Нет, вполне реально. Просто на обычных скриптовых языках это пишется быстрее, и читается лучше.
bormand 13.09.2013 07:51 # +1
guest 13.09.2013 09:34 # 0
Дык и говорю: питон такой весь в белом, а как присмотришься - из посикса всякую дрянь тащит. Говорят, фича скрытых файлов возникла из за "оптимизации" ислючения "." и ".." из вывода ls.
> способ с find багует
Да вроде нет: он в зависимости от tty выводит либо "..?", либо честно, добавьте "| cat".
bormand 13.09.2013 10:44 # 0
Вполне возможно. А ".." всяко возникла из-за "оптимизации" первых файловых систем - чтобы в качестве айдишки каталога/файла юзать только одно число, и по нему легко было бы узнавать родительский каталог.
> Да вроде нет
Ну я вот тестил for i in твойкод; do echo "[$i]"; done. Имя файла с пробелом в имени разорвало пополам. Надо или IFS менять на \n, или юзать find + exec вместо for + find. Тогда работает.
UPD: Рвет имена не с энтером, а с пробелом. А при IFS = \n начнет наоборот.
guest 13.09.2013 12:33 # 0
Это "как бы" весь юз-кейс был: с for-ом и print-ом.
anonimb84a2f6fd141 15.09.2013 03:45 # −2
inkanus-gray 28.02.2016 15:23 # 0
Пизне́с, насяйника!
Даже в ДОСе таких проблем не было!
Разворачивание масок шеллом не нужно.
3_14dar 28.02.2016 16:12 # 0
inkanus-gray 28.02.2016 17:17 # 0
В ДОС это не протолкнули по счастливой случайности: длина командной строки была ограничена и больше пары десятков файлов туда бы не пролезло. В результате досовскому софту пришлось разворачивать маски, что и унаследовала Винда.
3_14dar 28.02.2016 20:01 # +1
Ну объективно говоря, шелл что в досе, что в винде всегда был говном. Так что можно сказать, что прыщешелл слишком гибкий, гибкий не там где надо.
3_14dar 29.02.2016 10:03 # 0
bormand 12.09.2013 11:21 # +3
Я еле создал файл с переводом строки в имени. Пришлось привлечь к делу сишку. Откуда он вообще появился? :)
P.S. Последнее время мне приходит в голову мысль, что баш не нужен. Если его юзать не читая манов, на интуиции, то ловится куча ошибок. А если читать маны и писать аккуратно - то проще юзать какой-нибудь питон или перл: в них хотя бы логика есть, а не только исторически сложившиеся читы.
wvxvw 12.09.2013 13:56 # 0
tr в помощь, можно и не такое создать, даже пустую строку можно.
bormand 12.09.2013 15:04 # 0
wvxvw 12.09.2013 15:41 # +1
* ls не покажет перенос строки в имени файла по каким-то своим соображениям, скорее всего изза форматирования.
bormand 12.09.2013 16:04 # 0
wvxvw 12.09.2013 16:35 # 0
anonimb84a2f6fd141 15.09.2013 03:48 # 0
bormand 12.09.2013 11:31 # 0
unu-foja 12.09.2013 19:20 # 0
guest 12.09.2013 23:51 # −7
[email protected] (Спросить Тараса)
guest 13.09.2013 23:35 # −7
wvxvw 12.09.2013 13:53 # 0
guest 12.09.2013 23:51 # −8
[email protected] (Спросить Тараса)
Bobik 13.09.2013 12:51 # +3
mkdir $1
# do something
rm -rf $1/*
root@server:~ # ./test.sh
bormand 13.09.2013 14:02 # +2
nvidia тоже когда-то неплохо потроллила юзеров примерно такой командой:
guest 13.09.2013 20:28 # +3
bormand 13.09.2013 21:30 # 0
guest 13.09.2013 23:34 # −10
Dummy00001 14.09.2013 16:39 # 0
guest 17.09.2013 12:47 # −12