Видео ролики бесплатно онлайн

Смотреть красотки видео

Официальный сайт tali-sk 24/7/365

Смотреть видео бесплатно

Isquariel 11.06.2012 21:10

Скрипты на bashТренировка: самописная корзина

Опять побеспокою вас своим скриптопейсательством. Написала как бы корзину (я понимаю, что есть уже множество готовых решений). Файлы можно сжимать, а можно и не сжимать (определяется пользователем), все складываются в определённую папку, которая берётся из соответствующей переменной окружения, или складываются в $HOME/recycler, если такая папка не задана. Ну и корзина удаляет файлы, хранящиеся там более времени, заданного в R_TIME, либо, если эта переменная не задана, более 24 часов.

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/bin/bash

# Эта функция выводит руководство

function usage() {
echo
echo "Usage: bash $0 [options] files"
echo
echo " -c сжать файлы"
echo " -f пропускать предупреждения"
echo " -h показать это руководство"
echo " -R удалять папки рекурсивно"
echo
exit
}

# Задание переменных по-умолчанию

FORCE="-i" # Показывать предупреждения
TYPE="" # Без сжатия
LOG=`pwd`"/myrm.log"
FILELIST=""
cat /dev/null > "$LOG" # Создаём лог-файл

if [ $# = 0 ]; then # Если аргументов нет, то

a=""
until [ "$a" = "y" ] || [ "$a" = "n" ]; do
read -p "Сжать данные?(y/n): " a # Считываем тип архива
[ "$a" = "y" ] && TYPE=".7z"
done

a=""
until [ "$a" = "y" ] || [ "$a" = "n" ]; do
read -p "Спрашивать подтверждение?(y/n): " a # Считываем подтверждение
[ "$a" = "n" ] && FORCE="-f" # Если ответили нет, то убираем подтверждение
done

a=""
until [ "$a" = "y" ] || [ "$a" = "n" ]; do
read -p "Удалять папки рекурсивно?(y/n): " a # Считваем рекурсивность
[ "$a" = "y" ] && REC="-R"
done

read -p "Какие файлы следует удалить? " FILELIST

else
while getopts "cfRh" OPTION; do # Считываем опции
case "$OPTION" in
c) TYPE=".7z" ;; # Тип архива
R) REC="-R" ;; # Рекурсия
h) usage ;; # Выводим справку
f) FORCE="-f" ;; # Убираем подтверждения
*) usage ;; # Выводим справку
esac
done
shift $(($OPTIND - 1)) # Перемещаем указатель на следующий аргумент
fi

: ${R_TIME:=86400} # Задаём время в 24 часа (в секундах) если не задано

: ${R_DIR:="$HOME/recycler"} # Задаём папку корзины если она не задана

if ! [ -d "$R_DIR" ]; then # Если не существует такой корзины
if ! mkdir "$R_DIR"; then # Пытаемся её создать
echo "Cannot find Recycler Directory" # И если не удаётся, сообщаем об этом
exit # И выходим
fi
fi

find $R_DIR \! -newermt "$R_TIME seconds ago" -delete # Удаляем все файлы из корзины, помещённые туда раньше r_time

if [ -z "$FILELIST" ]; then
FILELIST=$@
fi

for i in "$FILELIST" # Для каждого аргумента
do
if [ -e "$i" ]; then # Если файл существует

o="$i$TYPE" # Получаем имя архива

if [ "$i" = "$o" ]; then # Если имена совпадают ($TYPE = "")
cp "$i" "$R_DIR/$o" >> "$LOG" # Копируем файл в корзину
else
7z a "$R_DIR/$o" "$i" >> "$LOG" # Иначе архивируем файл в корзину
fi

if [ -f "$i" ]; then # Если это файл
if ! rm "$FORCE" "$i"; then # Удаляем его, а если не получилось
rm -f "$R_DIR/$o" # Удаляем его из корзины
fi
elif [ -d "$i" ]; then # А если папка
if ! rm "$REC" "$FORCE" "$i"; then # Удаляем её, а если не получилось
rm -Rf "$R_DIR/$o" # Удаляем её из корзины
fi
else
rm -f "$R_DIR/$o"
fi

fi
done



Тэги: bash
+ 8 -
Похожие Поделиться

Ярослав 11.06.2012 22:33 #
+ 5 -
Я вас люблю.
le087 12.06.2012 00:20 #
+ 1 -
Я вас люблю.

Конечно, твои чувства прекрасны... Но сейчас от них толку нет. Лучше бы по скрипту что подсказал, а то у нас и так девушек дифицит.
blackraven 12.06.2012 13:46 #
+ 2 -
Ну дык он по скрипту...
За такое форматирование и оформление нельзя не влюбиться ;)
mealsforall 11.06.2012 22:42 #
+ 1 -
cat /dev/null > "$LOG", чтобы его сразу опустошить? Если просто для создания, то touch $LOG чуть проще.

until [ "$a" = "y" ] || [ "$a" = "n" ] можно сэкономить дл
until [[ $a == "y" || $a == "n" ]]

А так +1 за читабельный стиль.
Isquariel 12.06.2012 08:44 #
+ 2 -
Да, это чтобы опустошить лог перед записью.
kstep 12.06.2012 11:42 #
+ 0 -
truncate-же:

truncate -s 0 "$LOG"
koom 12.06.2012 12:05 #
+ 0 -
да вы тут из одной спецшколы все собрались, как я вижу
в моей же обычной школе, во всех примерах для обнуления файла всю жизнь использовалось
echo>file
kstep 12.06.2012 12:18 #
+ 0 -
Я тебе могу назвать кучу способов это сделать. Тем линукс и хорош. А расширять кругозор никогда не поздно. Почитай man truncate, эта команда специально для целей сброса файла создана. И системный вызов такой есть, кстати.
kstep 12.06.2012 12:19 #
+ 0 -
А твой способ не сбросит файл до размера 0, он запишет в файл 1 байт: LF. Дальнейшее дополнение в файл будет со второй строки, первая строка будет пустая.
mironov_orig 12.06.2012 20:03 #
+ 0 -
echo -n > file
kstep 13.06.2012 21:45 #
+ 0 -
Так да, покатит за альтернативу.
koom 15.06.2012 21:31 #
+ 1 -
про echo я загнал, после школы многое изменилось
Самый простой вариант это:
>file
Isquariel 13.06.2012 20:14 #
+ 1 -
Баш? В школе? Зависть.
koom 11.06.2012 23:03 #
+ 1 -
cat /dev/null > "$LOG"
Жесть, это где такому учат?
mealsforall 11.06.2012 23:36 #
+ 1 -
Это если ты влез в чужой компутер, а wtmp тебе удалить не дают, то делаешь именно так.
kstep 12.06.2012 11:43 #
+ 2 -
И ещё, я бы всю логику копирования в корзину и удаления оригинала сделал с помощью mv, получилось бы проще и быстрее.
kstep 12.06.2012 11:50 #
+ 2 -
Ещё идея возникла: сделать корзину в виде 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.
blackraven 12.06.2012 13:45 #
+ 0 -
Как вариант, переименовывать файлы в, например, хеш (sha512-хеш файла), и в папке корзины держать файл соответствия хеша имени файла. Причем имя файла записывать туда полным:

popd `dirname $FILENAME`
FQ_NAME="`pwd`/`basename $FILENAME`"
pushd

Как-то так.
kstep 13.06.2012 21:46 #
+ 0 -
FQ_NAME=$(realpath $FILENAME)
blackraven 18.06.2012 14:43 #
+ 0 -
Ну да, не вспомнил realpath, пришлось извернуться ;)
kstep 13.06.2012 21:53 #
+ 0 -
У твоего подхода есть минус. Хеш необратим => нельзя восстановить исходное имя файла для восстановления. С твоим подходом нужен ещё индексный файл с маппингом хеш => исходное имя файла.
uscr 14.06.2012 16:10 #
+ 0 -
Можно дописывать солёный хеш просто в конце имени файла. А в качестве соли брать unixdate, например.
blackraven 18.06.2012 14:42 #
+ 0 -
Дык а у меня чего написано?
в папке корзины держать файл соответствия хеша имени файла. Причем имя файла записывать туда полным
kstep 18.06.2012 20:11 #
+ 0 -
Упс, и правда. Каюсь, читал наискосок.
Isquariel 13.06.2012 20:16 #
+ 0 -
Действительно :(
koom 12.06.2012 12:10 #
+ -2 -
Вопрос для тренировки: зачем тут нужна запись вида
TYPE="" ?
kstep 12.06.2012 12:21 #
+ 0 -
Догадайся.
koom 12.06.2012 12:32 #
+ 0 -
Вопрос был не тебе, но ты тоже можешь попробовать ответить
blackraven 12.06.2012 13:38 #
+ 0 -
Учимся читать комментарии в коде.
kstep 12.06.2012 14:57 #
+ 0 -
Судя по тону общения и возникающим вопросам, могу предположить, что опыта разработки более-менее серьёзных приложений у тебя либо мало, либо вообще нет.

Советую почитать МакКоннела, что ли, для начала.
koom 13.06.2012 00:51 #
+ -3 -
То, что blackraven не понимает, для чего нужна эта инициализация, это уже понятно
С тобой случай поинтереснее.
Ты видимо перепутал bash с basic (это немудрено - оба начинаются на одинаковые буквы), раз тащишь в него парадигмы "совершенного кода"
МакКоннела я не читал и не планирую, но надеюсь ты меня просвятишь, что имел в виду ТС (уж он то по твоему мнению точно читал МакКоннела, как я понимаю)
ananas 13.06.2012 15:13 #
+ 0 -
export TYPE="; rm -rf ~" перед скриптом, и корзина не нужна
koom 13.06.2012 17:11 #
+ -3 -
Ай, красава,фруктовый ты мой, ай уел. Прям чувствуется школа ЛОРа.
Наконец у нас вырисовывается поистине инфернальный портрет ТСа: прочитала "Совершенный код", да плюс к этому и специалист по безопасности прям.

Подозреваю из первых букв строк скрипта можно сложить какое-нибудь грозное послание Майкрософту или вирус
kstep 13.06.2012 21:54 #
+ 2 -
Предлагаю не троллить. Мы здесь обсуждаем код скрипта, а не личности.
cppmm 13.06.2012 22:02 #
+ 2 -
Ух ты, какой толстенький. Давненько такой школоты не забредало.
blackraven 18.06.2012 14:45 #
+ 0 -
Его еще не забанили?..
kstep 13.06.2012 21:49 #
+ 1 -
«Не читал, но осуждаю.»

Парадигмы «Совершенного кода» применимы к любому языку.

Но раз уж ты понял, о чём идёт речь, есть надёжда, что ты не безнадёжен.
cppmm 13.06.2012 22:09 #
+ 1 -
Ты бы хотя бы ABS Guide осилил, прежде чем идти скрипты обсуждать. А заодно принципы работы в nix-системах. А то нагуглить по имени автора название книжки это легко. Но вот понять, о чём оно по описанию - это сложнее.
koom 14.06.2012 06:16 #
+ -3 -
Какое-то прям заболевание у вас ребята. Задан простой, казалось бы, вопрос, а вместо простого ответа, получаю только пафосные отсылки на умные книжки и демонизацию ТСа. Скучно с вами.
Лучще всех пока зарекомендовал себя ananas, его вариант действительно остроумный.
cppmm 14.06.2012 06:55 #
+ 0 -
А какой реакции ты ожидал, задав тупой вопрос?
cppmm 14.06.2012 07:12 #
+ 2 -
Предупреждая последующие вопросы предлагаю всё-таки почитать литературу и в качестве домашнего задания подумать, зачем переменные инициализируются перед использованием и что бывает, когда в переменной появляется неожидаемое содержимое или undef.
koom 14.06.2012 11:59 #
+ -3 -
Ты местный клоун что ли?
Сам то давно 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!'
koom 14.06.2012 12:01 #
+ -3 -
братишь, ты там знак доллара потерял в имени переменной в условии...
koom 14.06.2012 12:04 #
+ -3 -
ничо, kstep ему поможет с отладкой, если что
uscr 14.06.2012 16:02 #
+ 0 -
Забыл под вторым аккаунтом залогиниться, лошара.
koom 14.06.2012 16:30 #
+ -3 -
Ну наконец-то! А я то всё думал, когда же наконец можно будет перейти на личные оскорбления, а то всё скрипт да скрипт - скукота...
koom 14.06.2012 16:32 #
+ -1 -
Да, не говори, негативный братиша какой-то. Наверняка всё что можно было сказать он и так уже сказал своей книгой "Advanced Bash-Scripting Guide", теперь и в интернетах подерзить можно
uscr 14.06.2012 17:51 #
+ 0 -
Опять. Будь внимательнее.
koom 14.06.2012 19:24 #
+ -3 -
братиш, тоже считаешь, что штука повторенная дважды становится понятнее? Будешь себя хорошо вести, дам блеснуть остроумием еще раз.Давай начнем с опечаток, над которыми ты сможешь смешно пошутить?Думаю это увеличит твои шансы в глазах ТСа, а от твоих вялых каментов непосредственно по скрипту вряд ли она к тебе будет достаточно благосклонна
uscr 14.06.2012 21:59 #
+ 0 -
Я искренне надёялся, что ты похудеешь. А так... Ненавижу толстяков.
kstep 14.06.2012 13:03 #
+ 0 -
Эээ... У koom-а раздвоение личности? Кто там с ним рядом, вызовите скорую!
koom 14.06.2012 14:29 #
+ -1 -
Предлагаю не троллить. Мы здесь обсуждаем код скрипта, а не личности
OH WAIT...
cppmm 14.06.2012 22:20 #
+ 2 -
Ну не лез бы уже, раз мозгов нет:

1
2
3
4
5
6
7
8
9
#!/bin/bash

TESTVAR=""

: ${TESTVAR?}
echo "$TESTVAR"

: ${TESTVAR2?}
echo "$TESTVAR2"

koom 14.06.2012 22:36 #
+ -3 -
Ай ай ай, Антоша, что же ты так пенишься, никак обидеть хочешь? Ты не переживай так, это же всё невзаправду.
Но пошутили и будет...
Я всё никак не могу понять где тут "появляется неожидаемое содержимое"? Ты всё ходишь вокруг да около, словами умными бросаешься, пафос испускаешь, а конкретики что-то не видать. Печально это знаешь ли
cppmm 14.06.2012 22:52 #
+ 0 -
Кто пенится? Я просто указал на то, что ты глуп. :)
А этот пример указывает на то, что бывает при использовании неинициализированных переменных. Заодно показывает, что книжек ты таки не читал, глупышка. :)
Про неожиданное содержимое тебе уже выше пример выдавали.
И куда уж конкретнее писать? Тут тебе всем форумом говорят про ошибки, которые могут возникнуть из-за неинициализированных переменных. Подсказывают, что можно значение подефолту таким способом установить. Но ты упорно не хочешь слушать и продолжаешь устраивать клоунаду. Скучно.
koom 14.06.2012 23:27 #
+ -2 -
Антоша, давай я тебе ещё раз прозрачно намекну, что пора бы перестать хамить незнакомым cтаршим? Корявые понты не красят человека, поэтому "глупышку" жене своей оставь.

ananas тот ещё трикстер конечно, но его пример слишком надуман (так и другой процесс может в память напихать непонятного, да и вместо rm может быть что-то затейливое).
Мне всё-таки интересно насколько вероятны побочные эффекты использования неинициализированных переменных в контексте локальной области видимости, просто я никогда не заморачивался инициализацией.
Теоретизации не очень интересны, хотелось бы наглядной демонстрации, а твой пример ничего не показывает и не доказывает, либо я его неправильно понимаю

Современные компиляторы вообще больше и больше берут заботы об инициализации переменных на себя, так что я склонен думать, что это просто дань традициями и пережитки прошлого, не несущие практического смысла
cppmm 15.06.2012 01:34 #
+ 3 -
> Антоша, давай я тебе ещё раз прозрачно намекну, что пора бы перестать хамить незнакомым cтаршим?
Ой, извините, дяденька, телепатии не обучен, а по сообщениям на школьника похож сильно. :)

Наконец-то по делу разговор пошёл. И стоило столько кривляться прежде чем сразу ясно и понятно выразить свои мысли?

Пример от ananas не надуман. В системе огромное количество программ и многие из них используют в своей работе переменные окружения. Для bash-скрипта любая переменная практически равносильна переменной окружения. Стоит одному криворукому программисту в своей программе вызвать export TYPE со своим значением и наш скрипт без явного обнуления этой переменной будет по умолчанию использовать то, что там записано. И уже не важно, что там будет(rm или там просто случайный набор символов), скрипт отработает не верно.
Мой же пример является просто ответом на то, что даже в таком простом языке как bash есть разница между инициализированными переменными и неинициализированными. Именно в данном конкретном скрипте это незначительно. Но в другой раз может оказаться проверка на существование переменной и тут с твоим подходом мы рискуем наступить на грабли.
Подобные вещи должны сидеть в программистах на уровне рефлексов. Сначала объявляешь переменную, потом её используешь. Это как грамотное форматирование кода. Оно не всегда обязательно, но если его нет, программист хорошим быть не может, потому как это потенциальные ошибки и путаница.

Ну и я не совсем понял, какой именно конкретный пример нужен? Пример, где применяется такой подход? Да любой нормальный скрипт. Вот, выдержка из скрипта /etc/init.d/bind9 (debian squeezy):

1
2
3
4
5
6
# for a chrooted server: "-u bind -t /var/lib/named"
# Don't modify this line, change or create /etc/default/bind9.
OPTIONS=""
RESOLVCONF=no

test -f /etc/default/bind9 && . /etc/default/bind9


Если бы в данном примере не было объявления OPTIONS и этот параметр не был бы указан в /etc/default/bind9, то туда вполне возможно могло бы попасть оставшееся в этой переменной значение из другого скрипта. bind бы, разумеется, не понял, что там за параметры и упал бы при старте. Так понятно?

Что касается современных компиляторов, то они продвинулись довольно далеко со времён PDP-7 и иже с ними. Но всё-равно они не всемогущи. И если есть возможность перестраховаться и защитить себя от ошибок, то лучше это сделать. Особенно хорошо это понимаешь, когда скриптов и программ приходится писать много и такие вот мелкие "пережитки прошлого" в один прекрасный момент оказываются жизненно необходимы.
citi7en 15.06.2012 13:45 #
+ 0 -
Стоит одному криворукому программисту в своей программе вызвать export TYPE со своим значением и наш скрипт без явного обнуления этой переменной будет по умолчанию использовать то, что там записано.

Не совсем так. export TYPE внутри программы будет действовать только в окружении процесса этой программы. Это не повлияет на параллельно запускаемый скрипт или запущенный после него.
cppmm 16.06.2012 01:06 #
+ 1 -
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌┤~/wtmp/welinux├─────────────────────────────────────────────────┤cppmm@damned├─
└─> cat > welinux.sh << EOFILE
> #!/bin/bash
> KOOM="koom"
> export KOOM
> EOFILE
┌┤~/wtmp/welinux├─────────────────────────────────────────────────┤cppmm@damned├─
└─> cat > welinux1.sh << EOFILE
> #!/bin/bash
> echo $KOOM
> EOFILE
┌┤~/wtmp/welinux├─────────────────────────────────────────────────┤cppmm@damned├─
└─> bash welinux.sh
┌┤~/wtmp/welinux├─────────────────────────────────────────────────┤cppmm@damned├─
└─> bash welinux1.sh
koom

citi7en 18.06.2012 15:41 #
+ 1 -
Не воспроизводится на двух системах:
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 была объявлена ранее.
cppmm 19.06.2012 00:16 #
+ 1 -
Да, извиняюсь, у меня в примере ошибка была. Почему-то значение автоматом подставилось.
Но при вызове bash'а эмулятор терминала может установить свои переменные, некоторые программы могут добавлять свои опции в .bashrc или profile, где export уже отлично работает и всё, что там указано замечательно применяется нашими скриптами, так как они являются как раз дочерними процессами для запущенной версии bash.
И как ни крути всегда есть вероятность, что в нужной нам переменной может находиться неожиданное значение. Я об этом пытаюсь объяснить.
citi7en 19.06.2012 13:43 #
+ 1 -
Против этого возражений нет. Изначально, я поправил вас относительно взаимовлияния параллельно или последовательно запущенных скриптов. С этим, вроде, разобрались.
blackraven 18.06.2012 14:51 #
+ 0 -
если просто сказать
TYPE=""
то да, не повлияет. Если сказать export - повлияет. Что, кстати, и используется часто, когда разделяют, например, инициализацию окружения и собственно стартап-скрипт.
citi7en 18.06.2012 16:36 #
+ 0 -
export задаёт переменные, которые будут наследоваться чайлд-процессами.
Если необходимо инициализировать текущее окружение при помощи скрита, то необходимо выполнить

1
source $script_name

или
1
. $script_name

Daria 13.06.2012 03:50 #
+ 2 -
можешь вставить туда любой свой способ сжатия по умолчанию.
uscr 14.06.2012 16:09 #
+ 1 -
По юзабилити: это хорошая идея, ведь теперь можно смело работать под рутом только отвечать на кучу вопросов перед удалением каждого файла, а тем более руками вводить имя файла - гемор. Предлагаю сделать так:

при запуске mysr с параметром interact - задавать все эти вопросы. Без параметра проверять, передали ли имя файла, если нет - спросить его, если передали - удалить с дефолтными параметрами. Реализуется так:

1
2
3
4
5
6
7
8
case $1 in
'interact')
interact
;;
*
default $2
;;
esac


Ну и в функции default сделать проверку:

1
2
3
if [ -z "$1" ]; then
ack_filename
fi

uscr 14.06.2012 17:52 #
+ 0 -
s/myrs/myrm

Смотреть видео онлайн

Онлайн видео бесплатно


Смотреть русское с разговорами видео

Online video HD

Видео скачать на телефон

Русские фильмы бесплатно

Full HD video online

Смотреть видео онлайн

Смотреть HD видео бесплатно

School смотреть онлайн