-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask16.sh
More file actions
104 lines (97 loc) · 8.6 KB
/
task16.sh
File metadata and controls
104 lines (97 loc) · 8.6 KB
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
103
104
: '
Напишите программный код по заданию ниже на SHELL. Загрузите .sh файл для оценки.
Задание:
Написать shell-скрипт поиска и удаления по запросу во всех каталогах, имеющих общий
родительский каталог, файлов с расширением txt. Предусмотреть возможность неоднократного
прерывания по сигналу < Ctrl+C >.
При поступлении каждого сигнала прерывания выводить информацию о том, сколько файлов
уже удалено.
'
# Обработчик сигнала - функция handl:
handl() {
echo " Удалено файлов: $n"
if [ $flag -eq 0 ]; then # Если ввод еще не произведен, то запрос повторяется:
echo "Введите имя каталога:"
fi
}
: '
Установка нового обработчика handl при поступлении сигнала прерывания SIGINT (код 2),
по умолчанию вызывающего завершение процесса при нажатии < Ctrl+C > в терминале.
'
trap "handl" SIGINT
# Основная программа:
n=0 # Счетчик удаленных файлов.
flag=0 # Переменная для фиксации факта ввода пользователя.
echo "Введите имя каталога:"
read dirname # Чтение в переменную $dirname имени каталога, введенного с терминала
if test -d "$dirname"; then # Команда test с параметром -d проверяет, существует
# ли каталог $dirname, если он существует, то
flag=1 # ввод произведен.
# Если во время ввода поступит сигнал, то значение флага не изменится. Если ввод
# завершится успешно, то флаг станет равным единице.
else
echo "Каталог '$dirname' не существует!"
exit 1 # Команда exit закрывает оболочку со статусом 1.
fi
tmpfile=`mktemp` # Создание временного файла и запись его имени в переменную $tmpfile
if test $? -ne 0; then # Если возвращаемое значение последней команды не равняется нулю:
echo "Не удалось создать временный файл"
exit 2 # Команда exit закрывает оболочку со статусом 2.
fi
: '
Команда mktemp создает временный файл в системном каталоге "/tmp" и выводит его имя,
которое записывается в переменную $tmpfile.
Так как mktemp рандомизирует имена, столкновения имен не будет. Файл будет создан
с разрешением u + rw (600), т.е. только владелец файла может читать и писать в этот файл,
другие пользователи не могут получить к нему доступ. Временные файлы в соответствии со
своей диспозицей (т.е. временем жизни) исчезнут после перезагрузки ОС, поэтому не
обязательно чистить их вручную.
Обмен информацией между процессами с помощью временного файла позволяет корректно
обрабатывать файлы, в именах которых содержатся символы пробела, в отличии от
использования межпроцессного канала, замены символов перевода строки на пробелы с помощью
утилиты tr "\n" " " и дальнейшего последовательного чтения имен файлов из получившейся
длинной строки.
'
find $dirname -depth -type f -iname "*.txt" 2>/dev/null 1>$tmpfile
: '
Утилита find предусматривает неограниченное количество аргументов и применяется для
поиска всех файлов c расширением ".txt" в заданном каталоге и его подкаталогах:
$dirname (каталог поиска) - это отправной каталог, с которого find начинает поиск файлов
по всем подкаталогам, находящимся внутри.
параметр -depth - искать сначала в заданном каталоге, а потом в его подкаталогах.
параметр -type f - искать только обычные файлы (исключает символические ссылки и
каталоги, заканчивающиеся на ".txt").
критерий -iname - поиск по имени без учета регистра (будут найдены файлы "*.txt",
"*.TXT", "*.txT" и т.п.).
2>/dev/null - сообщения об ошибках будут перенаправляться в нулевое устройство, что
обеспечит более чистую выдачу.
1>$tmpfile - результаты поиска будут записаны в файл $tmpfile (перенаправление
стандартного вывода).
'
# Для построчного чтения файла используется перенаправление ввода в цикле while:
while read filename; do # Запуск цикла while и сохранение содержимого строки
# в переменную $filename.
if rm -f "$filename" 2>/dev/null; then # Удаление файла и проверка успешности удаления
# по коду возврата rm. Если файл с именем $filename удален,
echo "Удален файл '$filename'"
n=`expr $n + 1` # то счетчик удаленных файлов увеличивается,
sleep 2 # а выполнение работы программы замедляется на 2 секунды
# для того, чтобы пользователь успел нажать < Ctrl+C >.
else # В противном случае сообщается, что файл не удален.
echo "Не удалось удалить файл '$filename'"
fi
done <$tmpfile # Чтение содержимого файла $tmpfile с использованием
# перенаправления ввода и закрытие цикла с помощью done.
: '
Примечание: Параметр -f или --force указывает команде rm никогда не запрашивать
у пользователя подтверждение на удаление и не возвращать код ошибочного завершения, если
ошибки были вызваны несуществующими файлами, т.е., по сути, это принудительное удаление
файла. Однако этот параметр не удаляет файлы из каталога, если он защищен от записи.
В случае успеха команда rm не производит никакого вывода и возвращает ноль. Наиболее
вероятная ошибка: 1 ("Операция не разрешена"). Она произойдет, если у пользователя нет
прав на удаление файла.
'
rm "$tmpfile" # Временный файл удаляется.
exit 0 # Команда exit закрывает оболочку со статусом 0. В соответствии с
# соглашениями, 0 указывает на успешное завершение, в то время как
# ненулевое значение означает ошибку.