Isquariel 11.06.2012 21:10
Скрипты на bash — Тренировка: самописная корзина
Опять побеспокою вас своим скриптопейсательством. Написала как бы корзину (я понимаю, что есть уже множество готовых решений). Файлы можно сжимать, а можно и не сжимать (определяется пользователем), все складываются в определённую папку, которая берётся из соответствующей переменной окружения, или складываются в $HOME/recycler, если такая папка не задана. Ну и корзина удаляет файлы, хранящиеся там более времени, заданного в R_TIME, либо, если эта переменная не задана, более 24 часов.
Ярослав 11.06.2012 22:33 #
+ 5 -
Я вас люблю.
Я вас люблю.
Конечно, твои чувства прекрасны... Но сейчас от них толку нет. Лучше бы по скрипту что подсказал, а то у нас и так девушек дифицит.
Ну дык он по скрипту...
За такое форматирование и оформление нельзя не влюбиться ;)
За такое форматирование и оформление нельзя не влюбиться ;)
cat /dev/null > "$LOG", чтобы его сразу опустошить? Если просто для создания, то touch $LOG чуть проще.
until [ "$a" = "y" ] || [ "$a" = "n" ] можно сэкономить дл
until [[ $a == "y" || $a == "n" ]]
А так +1 за читабельный стиль.
until [ "$a" = "y" ] || [ "$a" = "n" ] можно сэкономить дл
until [[ $a == "y" || $a == "n" ]]
А так +1 за читабельный стиль.
да вы тут из одной спецшколы все собрались, как я вижу
в моей же обычной школе, во всех примерах для обнуления файла всю жизнь использовалось
echo>file
в моей же обычной школе, во всех примерах для обнуления файла всю жизнь использовалось
echo>file
Я тебе могу назвать кучу способов это сделать. Тем линукс и хорош. А расширять кругозор никогда не поздно. Почитай man truncate, эта команда специально для целей сброса файла создана. И системный вызов такой есть, кстати.
А твой способ не сбросит файл до размера 0, он запишет в файл 1 байт: LF. Дальнейшее дополнение в файл будет со второй строки, первая строка будет пустая.
про echo я загнал, после школы многое изменилось
Самый простой вариант это:
>file
Самый простой вариант это:
>file
Это если ты влез в чужой компутер, а wtmp тебе удалить не дают, то делаешь именно так.
И ещё, я бы всю логику копирования в корзину и удаления оригинала сделал с помощью mv, получилось бы проще и быстрее.
Ещё идея возникла: сделать корзину в виде tar-файла, а не каталога, дописывать в него файлы с полным путём.
А то сейчас я вижу такую проблему: как я понял ты копируешь файл по тому имени, что задано твоему скрипту. В итоге не будет работать:
myrm path/to/file.txt # ты копируешь path/to/file.txt ~/recycler/path/to/file.txt, каталога ~/recycler/path/to нет => epic fail
cd ~/one/dir && myrm file.txt # копируется в ~/recycler/file.txt
cd ~/two/dir && myrm file.txt # копируется в ~/recycler/file.txt
Это разные файлы, но второй раз первый файл в корзине перезапишется вторым => epic fail.
А то сейчас я вижу такую проблему: как я понял ты копируешь файл по тому имени, что задано твоему скрипту. В итоге не будет работать:
myrm path/to/file.txt # ты копируешь path/to/file.txt ~/recycler/path/to/file.txt, каталога ~/recycler/path/to нет => epic fail
cd ~/one/dir && myrm file.txt # копируется в ~/recycler/file.txt
cd ~/two/dir && myrm file.txt # копируется в ~/recycler/file.txt
Это разные файлы, но второй раз первый файл в корзине перезапишется вторым => epic fail.
Как вариант, переименовывать файлы в, например, хеш (sha512-хеш файла), и в папке корзины держать файл соответствия хеша имени файла. Причем имя файла записывать туда полным:
popd `dirname $FILENAME`
FQ_NAME="`pwd`/`basename $FILENAME`"
pushd
Как-то так.
popd `dirname $FILENAME`
FQ_NAME="`pwd`/`basename $FILENAME`"
pushd
Как-то так.
У твоего подхода есть минус. Хеш необратим => нельзя восстановить исходное имя файла для восстановления. С твоим подходом нужен ещё индексный файл с маппингом хеш => исходное имя файла.
Можно дописывать солёный хеш просто в конце имени файла. А в качестве соли брать unixdate, например.
Дык а у меня чего написано?
в папке корзины держать файл соответствия хеша имени файла. Причем имя файла записывать туда полным
Судя по тону общения и возникающим вопросам, могу предположить, что опыта разработки более-менее серьёзных приложений у тебя либо мало, либо вообще нет.
Советую почитать МакКоннела, что ли, для начала.
Советую почитать МакКоннела, что ли, для начала.
То, что blackraven не понимает, для чего нужна эта инициализация, это уже понятно
С тобой случай поинтереснее.
Ты видимо перепутал bash с basic (это немудрено - оба начинаются на одинаковые буквы), раз тащишь в него парадигмы "совершенного кода"
МакКоннела я не читал и не планирую, но надеюсь ты меня просвятишь, что имел в виду ТС (уж он то по твоему мнению точно читал МакКоннела, как я понимаю)
С тобой случай поинтереснее.
Ты видимо перепутал bash с basic (это немудрено - оба начинаются на одинаковые буквы), раз тащишь в него парадигмы "совершенного кода"
МакКоннела я не читал и не планирую, но надеюсь ты меня просвятишь, что имел в виду ТС (уж он то по твоему мнению точно читал МакКоннела, как я понимаю)
Ай, красава,фруктовый ты мой, ай уел. Прям чувствуется школа ЛОРа.
Наконец у нас вырисовывается поистине инфернальный портрет ТСа: прочитала "Совершенный код", да плюс к этому и специалист по безопасности прям.
Подозреваю из первых букв строк скрипта можно сложить какое-нибудь грозное послание Майкрософту или вирус
Наконец у нас вырисовывается поистине инфернальный портрет ТСа: прочитала "Совершенный код", да плюс к этому и специалист по безопасности прям.
Подозреваю из первых букв строк скрипта можно сложить какое-нибудь грозное послание Майкрософту или вирус
Предлагаю не троллить. Мы здесь обсуждаем код скрипта, а не личности.
«Не читал, но осуждаю.»
Парадигмы «Совершенного кода» применимы к любому языку.
Но раз уж ты понял, о чём идёт речь, есть надёжда, что ты не безнадёжен.
Парадигмы «Совершенного кода» применимы к любому языку.
Но раз уж ты понял, о чём идёт речь, есть надёжда, что ты не безнадёжен.
Ты бы хотя бы ABS Guide осилил, прежде чем идти скрипты обсуждать. А заодно принципы работы в nix-системах. А то нагуглить по имени автора название книжки это легко. Но вот понять, о чём оно по описанию - это сложнее.
Какое-то прям заболевание у вас ребята. Задан простой, казалось бы, вопрос, а вместо простого ответа, получаю только пафосные отсылки на умные книжки и демонизацию ТСа. Скучно с вами.
Лучще всех пока зарекомендовал себя ananas, его вариант действительно остроумный.
Лучще всех пока зарекомендовал себя ananas, его вариант действительно остроумный.
Предупреждая последующие вопросы предлагаю всё-таки почитать литературу и в качестве домашнего задания подумать, зачем переменные инициализируются перед использованием и что бывает, когда в переменной появляется неожидаемое содержимое или undef.
Ты местный клоун что ли?
Сам то давно ABS читал: An uninitialized variable has a "null" value -- no assigned value at all
Я написал программу которая выясняет прав ты или нет:
# testvar=""
# [[ -z "testvar" ]] && echo 'NULL!' || echo 'cppmm was right!'
# [[ -z "testvar2" ]] && echo 'NULL!' || echo 'cppmm was right!'
Сам то давно ABS читал: An uninitialized variable has a "null" value -- no assigned value at all
Я написал программу которая выясняет прав ты или нет:
# testvar=""
# [[ -z "testvar" ]] && echo 'NULL!' || echo 'cppmm was right!'
# [[ -z "testvar2" ]] && echo 'NULL!' || echo 'cppmm was right!'
братишь, ты там знак доллара потерял в имени переменной в условии...
Ну наконец-то! А я то всё думал, когда же наконец можно будет перейти на личные оскорбления, а то всё скрипт да скрипт - скукота...
Да, не говори, негативный братиша какой-то. Наверняка всё что можно было сказать он и так уже сказал своей книгой "Advanced Bash-Scripting Guide", теперь и в интернетах подерзить можно
братиш, тоже считаешь, что штука повторенная дважды становится понятнее? Будешь себя хорошо вести, дам блеснуть остроумием еще раз.Давай начнем с опечаток, над которыми ты сможешь смешно пошутить?Думаю это увеличит твои шансы в глазах ТСа, а от твоих вялых каментов непосредственно по скрипту вряд ли она к тебе будет достаточно благосклонна
Эээ... У koom-а раздвоение личности? Кто там с ним рядом, вызовите скорую!
Предлагаю не троллить. Мы здесь обсуждаем код скрипта, а не личности
OH WAIT...
OH WAIT...
Ай ай ай, Антоша, что же ты так пенишься, никак обидеть хочешь? Ты не переживай так, это же всё невзаправду.
Но пошутили и будет...
Я всё никак не могу понять где тут "появляется неожидаемое содержимое"? Ты всё ходишь вокруг да около, словами умными бросаешься, пафос испускаешь, а конкретики что-то не видать. Печально это знаешь ли
Но пошутили и будет...
Я всё никак не могу понять где тут "появляется неожидаемое содержимое"? Ты всё ходишь вокруг да около, словами умными бросаешься, пафос испускаешь, а конкретики что-то не видать. Печально это знаешь ли
Кто пенится? Я просто указал на то, что ты глуп. :)
А этот пример указывает на то, что бывает при использовании неинициализированных переменных. Заодно показывает, что книжек ты таки не читал, глупышка. :)
Про неожиданное содержимое тебе уже выше пример выдавали.
И куда уж конкретнее писать? Тут тебе всем форумом говорят про ошибки, которые могут возникнуть из-за неинициализированных переменных. Подсказывают, что можно значение подефолту таким способом установить. Но ты упорно не хочешь слушать и продолжаешь устраивать клоунаду. Скучно.
А этот пример указывает на то, что бывает при использовании неинициализированных переменных. Заодно показывает, что книжек ты таки не читал, глупышка. :)
Про неожиданное содержимое тебе уже выше пример выдавали.
И куда уж конкретнее писать? Тут тебе всем форумом говорят про ошибки, которые могут возникнуть из-за неинициализированных переменных. Подсказывают, что можно значение подефолту таким способом установить. Но ты упорно не хочешь слушать и продолжаешь устраивать клоунаду. Скучно.
Антоша, давай я тебе ещё раз прозрачно намекну, что пора бы перестать хамить незнакомым cтаршим? Корявые понты не красят человека, поэтому "глупышку" жене своей оставь.
ananas тот ещё трикстер конечно, но его пример слишком надуман (так и другой процесс может в память напихать непонятного, да и вместо rm может быть что-то затейливое).
Мне всё-таки интересно насколько вероятны побочные эффекты использования неинициализированных переменных в контексте локальной области видимости, просто я никогда не заморачивался инициализацией.
Теоретизации не очень интересны, хотелось бы наглядной демонстрации, а твой пример ничего не показывает и не доказывает, либо я его неправильно понимаю
Современные компиляторы вообще больше и больше берут заботы об инициализации переменных на себя, так что я склонен думать, что это просто дань традициями и пережитки прошлого, не несущие практического смысла
ananas тот ещё трикстер конечно, но его пример слишком надуман (так и другой процесс может в память напихать непонятного, да и вместо rm может быть что-то затейливое).
Мне всё-таки интересно насколько вероятны побочные эффекты использования неинициализированных переменных в контексте локальной области видимости, просто я никогда не заморачивался инициализацией.
Теоретизации не очень интересны, хотелось бы наглядной демонстрации, а твой пример ничего не показывает и не доказывает, либо я его неправильно понимаю
Современные компиляторы вообще больше и больше берут заботы об инициализации переменных на себя, так что я склонен думать, что это просто дань традициями и пережитки прошлого, не несущие практического смысла
> Антоша, давай я тебе ещё раз прозрачно намекну, что пора бы перестать хамить незнакомым cтаршим?
Ой, извините, дяденька, телепатии не обучен, а по сообщениям на школьника похож сильно. :)
Наконец-то по делу разговор пошёл. И стоило столько кривляться прежде чем сразу ясно и понятно выразить свои мысли?
Пример от ananas не надуман. В системе огромное количество программ и многие из них используют в своей работе переменные окружения. Для bash-скрипта любая переменная практически равносильна переменной окружения. Стоит одному криворукому программисту в своей программе вызвать export TYPE со своим значением и наш скрипт без явного обнуления этой переменной будет по умолчанию использовать то, что там записано. И уже не важно, что там будет(rm или там просто случайный набор символов), скрипт отработает не верно.
Мой же пример является просто ответом на то, что даже в таком простом языке как bash есть разница между инициализированными переменными и неинициализированными. Именно в данном конкретном скрипте это незначительно. Но в другой раз может оказаться проверка на существование переменной и тут с твоим подходом мы рискуем наступить на грабли.
Подобные вещи должны сидеть в программистах на уровне рефлексов. Сначала объявляешь переменную, потом её используешь. Это как грамотное форматирование кода. Оно не всегда обязательно, но если его нет, программист хорошим быть не может, потому как это потенциальные ошибки и путаница.
Ну и я не совсем понял, какой именно конкретный пример нужен? Пример, где применяется такой подход? Да любой нормальный скрипт. Вот, выдержка из скрипта /etc/init.d/bind9 (debian squeezy):
Если бы в данном примере не было объявления OPTIONS и этот параметр не был бы указан в /etc/default/bind9, то туда вполне возможно могло бы попасть оставшееся в этой переменной значение из другого скрипта. bind бы, разумеется, не понял, что там за параметры и упал бы при старте. Так понятно?
Что касается современных компиляторов, то они продвинулись довольно далеко со времён PDP-7 и иже с ними. Но всё-равно они не всемогущи. И если есть возможность перестраховаться и защитить себя от ошибок, то лучше это сделать. Особенно хорошо это понимаешь, когда скриптов и программ приходится писать много и такие вот мелкие "пережитки прошлого" в один прекрасный момент оказываются жизненно необходимы.
Ой, извините, дяденька, телепатии не обучен, а по сообщениям на школьника похож сильно. :)
Наконец-то по делу разговор пошёл. И стоило столько кривляться прежде чем сразу ясно и понятно выразить свои мысли?
Пример от ananas не надуман. В системе огромное количество программ и многие из них используют в своей работе переменные окружения. Для bash-скрипта любая переменная практически равносильна переменной окружения. Стоит одному криворукому программисту в своей программе вызвать export TYPE со своим значением и наш скрипт без явного обнуления этой переменной будет по умолчанию использовать то, что там записано. И уже не важно, что там будет(rm или там просто случайный набор символов), скрипт отработает не верно.
Мой же пример является просто ответом на то, что даже в таком простом языке как bash есть разница между инициализированными переменными и неинициализированными. Именно в данном конкретном скрипте это незначительно. Но в другой раз может оказаться проверка на существование переменной и тут с твоим подходом мы рискуем наступить на грабли.
Подобные вещи должны сидеть в программистах на уровне рефлексов. Сначала объявляешь переменную, потом её используешь. Это как грамотное форматирование кода. Оно не всегда обязательно, но если его нет, программист хорошим быть не может, потому как это потенциальные ошибки и путаница.
Ну и я не совсем понял, какой именно конкретный пример нужен? Пример, где применяется такой подход? Да любой нормальный скрипт. Вот, выдержка из скрипта /etc/init.d/bind9 (debian squeezy):
1 |
# for a chrooted server: "-u bind -t /var/lib/named"
|
Если бы в данном примере не было объявления OPTIONS и этот параметр не был бы указан в /etc/default/bind9, то туда вполне возможно могло бы попасть оставшееся в этой переменной значение из другого скрипта. bind бы, разумеется, не понял, что там за параметры и упал бы при старте. Так понятно?
Что касается современных компиляторов, то они продвинулись довольно далеко со времён PDP-7 и иже с ними. Но всё-равно они не всемогущи. И если есть возможность перестраховаться и защитить себя от ошибок, то лучше это сделать. Особенно хорошо это понимаешь, когда скриптов и программ приходится писать много и такие вот мелкие "пережитки прошлого" в один прекрасный момент оказываются жизненно необходимы.
Стоит одному криворукому программисту в своей программе вызвать export TYPE со своим значением и наш скрипт без явного обнуления этой переменной будет по умолчанию использовать то, что там записано.
Не совсем так. export TYPE внутри программы будет действовать только в окружении процесса этой программы. Это не повлияет на параллельно запускаемый скрипт или запущенный после него.
Не воспроизводится на двух системах:
1.
$ uname -r
2.6.32-5-sparc64
$ bash -version
GNU bash, version 4.1.5(1)-release (sparc-unknown-linux-gnu)
2.
$ uname -r
2.6.32-202.el6.i686
$ bash -version
GNU bash, version 4.1.2(1)-release (i386-redhat-linux-gnu)
Но так и не должно быть пруф.
Если у вас это работает, ваша система уязвима. Проверьте, может быть у вас объявлен альяс типа bash='.', или сам /bin/bash подхачен. Хотя, может просто переменная KOOM была объявлена ранее.
1.
$ uname -r
2.6.32-5-sparc64
$ bash -version
GNU bash, version 4.1.5(1)-release (sparc-unknown-linux-gnu)
2.
$ uname -r
2.6.32-202.el6.i686
$ bash -version
GNU bash, version 4.1.2(1)-release (i386-redhat-linux-gnu)
Но так и не должно быть пруф.
Если у вас это работает, ваша система уязвима. Проверьте, может быть у вас объявлен альяс типа bash='.', или сам /bin/bash подхачен. Хотя, может просто переменная KOOM была объявлена ранее.
Да, извиняюсь, у меня в примере ошибка была. Почему-то значение автоматом подставилось.
Но при вызове bash'а эмулятор терминала может установить свои переменные, некоторые программы могут добавлять свои опции в .bashrc или profile, где export уже отлично работает и всё, что там указано замечательно применяется нашими скриптами, так как они являются как раз дочерними процессами для запущенной версии bash.
И как ни крути всегда есть вероятность, что в нужной нам переменной может находиться неожиданное значение. Я об этом пытаюсь объяснить.
Но при вызове bash'а эмулятор терминала может установить свои переменные, некоторые программы могут добавлять свои опции в .bashrc или profile, где export уже отлично работает и всё, что там указано замечательно применяется нашими скриптами, так как они являются как раз дочерними процессами для запущенной версии bash.
И как ни крути всегда есть вероятность, что в нужной нам переменной может находиться неожиданное значение. Я об этом пытаюсь объяснить.
Против этого возражений нет. Изначально, я поправил вас относительно взаимовлияния параллельно или последовательно запущенных скриптов. С этим, вроде, разобрались.
если просто сказать
TYPE=""
то да, не повлияет. Если сказать export - повлияет. Что, кстати, и используется часто, когда разделяют, например, инициализацию окружения и собственно стартап-скрипт.
TYPE=""
то да, не повлияет. Если сказать export - повлияет. Что, кстати, и используется часто, когда разделяют, например, инициализацию окружения и собственно стартап-скрипт.
По юзабилити: это хорошая идея, ведь теперь можно смело работать под рутом только отвечать на кучу вопросов перед удалением каждого файла, а тем более руками вводить имя файла - гемор. Предлагаю сделать так:
при запуске mysr с параметром interact - задавать все эти вопросы. Без параметра проверять, передали ли имя файла, если нет - спросить его, если передали - удалить с дефолтными параметрами. Реализуется так:
Ну и в функции default сделать проверку:
при запуске mysr с параметром interact - задавать все эти вопросы. Без параметра проверять, передали ли имя файла, если нет - спросить его, если передали - удалить с дефолтными параметрами. Реализуется так:
1 |
|
Ну и в функции default сделать проверку:
1 |
|