Skip to content

Commit bb6facd

Browse files
authored
Add files via upload
1 parent b662a22 commit bb6facd

4 files changed

Lines changed: 265 additions & 36 deletions

File tree

clean_snap.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
#Removes old revisions of snaps
3+
#CLOSE ALL SNAPS BEFORE RUNNING THIS
4+
set -eu
5+
LANG=en_US.UTF-8
6+
snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do
7+
echo "$snapname" "$revision"
8+
snap remove "$snapname" --revision="$revision"
9+
done

find.py

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ def snapshot(self):
7676

7777
def find_directories(path, max_depth=1, size_filter=None, name_filter=None, exclude_dirs=None):
7878
"""
79-
Поиск директорий с заданными параметрами.
80-
81-
Аргументы:
79+
Searching for directories with specified parameters.
80+
81+
Arguments:
8282
path -- root dir to start from
83-
max_depth -- max deep to search
84-
size_filter -- фильтр по размеру (например, '>2G')
85-
name_filter -- фильтр по имени директории
86-
exclude_dirs -- список директорий для исключения
87-
88-
Возвращает список кортежей (размер, путь)
83+
max_depth -- max depth to search
84+
size_filter -- size filter (e.g., '>2G')
85+
name_filter -- directory name filter
86+
exclude_dirs -- list of directories to exclude
87+
88+
Returns a list of tuples (size, path)
8989
"""
9090

9191
if exclude_dirs is None:
@@ -96,7 +96,7 @@ def find_directories(path, max_depth=1, size_filter=None, name_filter=None, excl
9696
size_cache = FastThreadSafeCache() # Cache for storing directory sizes
9797

9898
log_message(f"Поиск в: {path}, макс. глубина: {max_depth}")
99-
log_message(f"Фильтры: размер = '{size_filter or ''}', имя = '{name_filter or ''}'")
99+
log_message(f"Фильтры: {Colors.RED}размер = '{size_filter or ''}'{Colors.RESET}, {Colors.MAGENTA}имя = '{name_filter or ''}'{Colors.RESET}")
100100
log_message(f"Исключения: {exclude_dirs}\n")
101101

102102

@@ -165,23 +165,6 @@ def calculate_size(current_path):
165165
return total_size
166166

167167

168-
def build_directory_tree(results):
169-
"""Build the tree of directories from the Result"""
170-
tree = defaultdict(dict)
171-
for item in sorted(results, key=lambda x: x["path"]):
172-
parts = item["path"].split(os.sep)
173-
current = tree
174-
has_leaf = len(parts) > 2
175-
for part in parts[1:]: # Пропускаем пустой первый элемент для абсолютных путей
176-
if part not in current:
177-
current[part] = defaultdict(dict)
178-
current = current[part]
179-
current["__leaf__"] = has_leaf and part == parts[-1]
180-
181-
current["__size__"] = item["size"]
182-
current["__raw_size__"] = item["raw_size"]
183-
return tree
184-
185168
def traverse_directories(start_path):
186169
"""Base function for traverse directories"""
187170
# pool with X workers
@@ -365,28 +348,47 @@ def pad_with_spaces(text, target_length, align='left'):
365348
Возвращает:
366349
str: строка, дополненная пробелами
367350
"""
368-
if len(text) >= target_length:
369-
return text
370-
351+
result = ''
371352
spaces_needed = target_length - len(text)
372353

373-
if align == 'left':
374-
return text + ' ' * spaces_needed
354+
if len(text) >= target_length:
355+
result = text
356+
357+
elif align == 'left':
358+
result = text + ' ' * spaces_needed
375359
elif align == 'right':
376-
return ' ' * spaces_needed + text
360+
result = ' ' * spaces_needed + text
377361
elif align == 'center':
378362
left_spaces = spaces_needed // 2
379363
right_spaces = spaces_needed - left_spaces
380-
return ' ' * left_spaces + text + ' ' * right_spaces
364+
result = ' ' * left_spaces + text + ' ' * right_spaces
381365
else:
382366
raise ValueError("Недопустимое значение align. Допустимо: 'left', 'right', 'center'")
367+
368+
return result
369+
370+
def build_directory_tree(results):
371+
"""Build the tree of directories from the Result"""
372+
tree = defaultdict(dict)
373+
for item in sorted(results, key=lambda x: x["path"]):
374+
parts = item["path"].split(os.sep)
375+
current = tree
376+
has_leaf = len(parts) > 1
377+
for part in parts[1:]: # Пропускаем пустой первый элемент для абсолютных путей
378+
if part not in current:
379+
current[part] = defaultdict(dict)
380+
current = current[part]
381+
current["__leaf__"] = has_leaf and part == parts[-1]
382+
383+
current["__size__"] = item["size"]
384+
current["__raw_size__"] = item["raw_size"]
385+
return tree
383386

384387
def print_directory_tree(tree, prefix=""):
385388
"""Рекурсивно печатает дерево директорий"""
386389
if not tree:
387390
return
388391

389-
log_message(f"\t\t\tTree.items: {tree.items()} {len(tree.items())}", False)
390392
items = sorted(
391393
[(k, v) for k, v in tree.items() if not k.startswith("__")],
392394
key=lambda x: x[1].get("__raw_size__", 0),
@@ -395,18 +397,22 @@ def print_directory_tree(tree, prefix=""):
395397

396398
for i, (name, subtree) in enumerate(items):
397399
is_last = i == len(items) - 1
400+
is_leaf = subtree.get("__leaf__")
398401
size = subtree.get("__size__", "")
399402
if size:
400403
size = f"({size})"
401404
# log_message(f"Node: {name} {size}", False)
402405

403406
if filterByName(name):
404407
name = f"{Colors.RED}{name}{Colors.RESET}"
405-
if subtree.get("__leaf__") and size_filter and filterBySize(subtree.get("__raw_size__", 0)):
408+
if is_leaf and size_filter and filterBySize(subtree.get("__raw_size__", 0)):
406409
size = f"{Colors.MAGENTA}{size}{Colors.RESET}"
407410

408411
if prefix == "":
409412
log_message(f"/{name} {size}")
413+
if is_leaf and subtree and not is_last :
414+
log_message(f"|")
415+
410416
else:
411417
log_message(f"{prefix}{'└── ' if is_last else '├── '}{name} {size}")
412418

freeup.sh

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#!/bin/bash
2+
3+
# Function to display disk usage
4+
# $dir - start directory count
5+
# $max_depth - Использование: $0 <директория> <максимальный_уровень_вложенности>
6+
# $size_filter - Пример фильтра: '>2G' для размера больше 2 Гб, '<100M' для размера меньше 100 Мб
7+
# $name_filter - Пример фильтра имени: 'documents' для директорий, содержащих 'documents' в имени
8+
display_disk_usage() {
9+
echo -e "\nAnalyze disk usage:"
10+
df -h /
11+
12+
local dir="$1"
13+
local max_depth="$2"
14+
local size_filter="$3"
15+
local name_filter="$4"
16+
17+
# Проверка аргументов
18+
if [ -z "$dir" ] || [ -z "$max_depth" ]; then
19+
echo "Использование: $0 <директория> <максимальный_уровень_вложенности>"
20+
echo "Пример фильтра: '>2G' для размера больше 2 Гб, '<100M' для размера меньше 100 Мб"
21+
echo "Пример фильтра имени: 'documents' для директорий, содержащих 'documents' в имени"
22+
return 1
23+
fi
24+
if [ ! -d "$dir" ]; then
25+
echo "Ошибка: Директория $dir не существует"
26+
return 1
27+
fi
28+
29+
time python3 find.py "$dir" "$max_depth" "$size_filter" "$name_filter" | while read -r line; do
30+
echo "$line"
31+
done
32+
}
33+
34+
35+
main() {
36+
# Проверка прав суперпользователя
37+
if [ "$EUID" -ne 0 ]; then
38+
echo "Пожалуйста, запустите этот скрипт с правами суперпользователя:"
39+
echo "sudo $0 $*"
40+
exit 1
41+
fi
42+
43+
echo "Remove apt and another old and garbage, temporary, logs"
44+
askExit
45+
df -h /
46+
47+
apt autoremove -y --purge
48+
apt clean -y
49+
apt autoclean -y
50+
51+
52+
# Removes old revisions of snaps
53+
# CLOSE ALL SNAPS BEFORE RUNNING THIS
54+
set -eu
55+
snap list --all | awk '/disabled/{print $1, $3}' | \
56+
while read snapname revision; do
57+
snap remove "$snapname" --revision="$revision"
58+
done
59+
60+
echo "Removing old kernels..."
61+
current_kernel=$(uname -r | sed "s/-generic//")
62+
dpkg -l 'linux-*' | sed "/^ii/!d;/"$current_kernel"/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d" | xargs apt-get -y purge
63+
64+
# Clear temporary files
65+
echo "Clearing temporary files..."
66+
rm -rf /tmp/*
67+
rm -rf /var/tmp/*
68+
rm -rf /etc/apk/cache/* /var/cache/* /var/lib/apt/lists/* /var/log/* /usr/share/doc/* /usr/share/man/*
69+
70+
# Empty trash
71+
echo "Emptying trash..."
72+
rm -rf ~/.local/share/Trash/*
73+
74+
# Remove thumbnail cache
75+
echo "Removing thumbnail cache..."
76+
rm -rf ~/.cache/thumbnails/*
77+
78+
LC_ALL=C dpkg -l | awk '/^rc/ {print $2}' | xargs sudo dpkg --purge --pending
79+
80+
#Removes old revisions of snaps
81+
#CLOSE ALL SNAPS BEFORE RUNNING THIS
82+
set -eu
83+
LANG=en_US.UTF-8
84+
snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do
85+
echo "$snapname" "$revision"
86+
snap remove "$snapname" --revision="$revision"
87+
done
88+
89+
90+
echo "journal systemd"
91+
journalctl --disk-usage
92+
journalctl --vacuum-time=7d
93+
94+
df -h /
95+
}
96+
97+
98+
# Функция для выполнения очистки файлов не входящих в пакеты Пакетного менеджера
99+
cruftCln() {
100+
# Проверка прав суперпользователя
101+
if [ "$EUID" -ne 0 ]; then
102+
echo "Пожалуйста, запустите этот скрипт с правами суперпользователя:"
103+
echo "sudo $0 $*"
104+
exit 1
105+
fi
106+
echo "Поиск ненужных файлов..."
107+
askExit
108+
109+
# Получаем список ненужных файлов
110+
cruft_files=$(sed -n '/---- missing: dpkg ----/,/---- unexplained: \/ ----/{
111+
/---- missing: dpkg ----/d
112+
/---- unexplained: \/ ----/d
113+
p
114+
}' cruft.log | grep -v '^end\.$')
115+
echo "$cruft_files" > cruft-mis-dpkg.log
116+
117+
# Подсчет общего освобождаемого пространства
118+
total_space=0
119+
echo "$cruft_files" | while read -r file; do
120+
if [ -e "$file" ]; then
121+
file_size=$(du -sb "$file" 2>/dev/null | cut -f1)
122+
if [ -n "$file_size" ]; then
123+
total_space=$(($total_space + $file_size))
124+
fi
125+
fi
126+
done
127+
128+
# Конвертация размера в удобочитаемый формат
129+
if [ $total_space -lt 1024 ]; then
130+
echo "Общее освобождаемое пространство: $total_space байт"
131+
elif [ $total_space -lt 1048576 ]; then
132+
echo "Общее освобождаемое пространство: $(echo "scale=2; $total_space/1024" | bc) КБ"
133+
elif [ $total_space -lt 1073741824 ]; then
134+
echo "Общее освобождаемое пространство: $(echo "scale=2; $total_space/1048576" | bc) МБ"
135+
else
136+
echo "Общее освобождаемое пространство: $(echo "scale=2; $total_space/1073741824" | bc) ГБ"
137+
fi
138+
139+
# Подтверждение очистки
140+
echo "Вы уверены, что хотите выполнить очистку? (y/n)"
141+
read -r confirm
142+
143+
if [ "$confirm" = "y" ]; then
144+
echo "$cruft_files" | while read -r file; do
145+
if [ -e "$file" ]; then
146+
if rm -rf "$file"; then
147+
echo "Удален: $file"
148+
else
149+
echo "Ошибка при удалении: $file"
150+
fi
151+
else
152+
echo "Пропущен (не существует): $file"
153+
fi
154+
done
155+
echo "Очистка завершена."
156+
else
157+
echo "Очистка отменена."
158+
fi
159+
}
160+
161+
cruftAnal() {
162+
echo "Выполнение сухой проверки..."
163+
cruft 2>&1 | tee cruft.log
164+
echo "Сухая проверка завершена."
165+
}
166+
167+
dockerCln() {
168+
echo "Clean up docker files"
169+
askExit
170+
171+
docker system prune --all --volumes
172+
docker image prune --all
173+
docker container prune
174+
175+
docker system df
176+
docker volume prune
177+
docker buildx prune --all
178+
}
179+
180+
askExit() {
181+
echo -e "\nStop? [y/n]"
182+
read -r answer
183+
if [ "$answer" = "y" ]; then exit 0; fi
184+
}
185+
186+
187+
while true; do
188+
# Display menu
189+
echo -e "\nДобро пожаловать в скрипт очистки ненужных файлов!"
190+
echo "Please select a function to execute:"
191+
echo -e "\e[31m\t1)\e[32m calculate disk usage"
192+
echo -e "\e[31m\t2)\e[32m main"
193+
echo -e "\e[31m\t3)\e[32m docker"
194+
echo -e "\e[31m\t4)\e[32m cruft cleanup from 'missing: dpkg' group"
195+
echo -e "\e[31m\t5)\e[32m cruft analyze"
196+
echo -e "\e[31m\t6)\e[32m compact FS"
197+
echo -e "\e[31m\t7)\e[32m exit"
198+
echo -e "\e[0m"
199+
# Read user input
200+
read -p "Enter a number: " choice
201+
echo ""
202+
203+
# Execute the chosen function
204+
case $choice in
205+
1) display_disk_usage "/" "1" ">1G" ;;
206+
2) main ;;
207+
3) sudo -u "$SUDO_USER" bash -c "$(declare -f dockerCln); dockerCln" ;;
208+
4) cruftCln ;;
209+
5) cruftAnal ;;
210+
6) e4defrag /dev/* ;;
211+
7) exit 0 ;;
212+
*) echo "Invalid input. Please enter a number from the list above" ;;
213+
esac
214+
done

image-1.png

16.7 KB
Loading

0 commit comments

Comments
 (0)