Загрузка данных
Листинг
remftrash
#!/bin/bash
# Функция для вывода ошибок
error_exit() {
echo "Ошибка: $1" >&2
exit 1
}
# Проверяем, правильно ли переданы параметры
if [ $# -ne 1 ]; then
error_exit "Неверное количество параметров"
fi
# Проверяем существование файла
if [ ! -f "$1" ]; then
error_exit "Файл '$1' не существует или не является обычным файлом"
fi
# Проверяем доступность файла для чтения
if [ ! -r "$1" ]; then
error_exit "Нет доступа на чтение файла '$1'"
fi
# Полный путь к исходному файлу
ORIGINAL_FILE=$(realpath "$1" 2>/dev/null)
if [ -z "$ORIGINAL_FILE" ]; then
error_exit "Не удалось получить полный путь к файлу '$1'"
fi
# Проверяем существование каталога trash, создаем если его нет
TRASH_DIR="$HOME/.trash"
if [ ! -d "$TRASH_DIR" ]; then
mkdir -p "$TRASH_DIR" 2>/dev/null
if [ ! -d "$TRASH_DIR" ]; then
error_exit "Не удалось создать каталог корзины '$TRASH_DIR'"
fi
fi
# Проверяем права на запись в каталог trash
if [ ! -w "$TRASH_DIR" ]; then
error_exit "Нет прав на запись в каталог корзины '$TRASH_DIR'"
fi
# Проверяем существование файла trash.log, создаем если его нет
TRASH_LOG="$HOME/.trash.log"
if [ ! -f "$TRASH_LOG" ]; then
touch "$TRASH_LOG" 2>/dev/null
if [ ! -f "$TRASH_LOG" ]; then
error_exit "Не удалось создать файл журнала '$TRASH_LOG'"
fi
fi
# Проверяем права на запись в файл trash.log
if [ ! -w "$TRASH_LOG" ]; then
error_exit "Нет прав на запись в файл журнала '$TRASH_LOG'"
fi
# Находим новое уникальное имя для файла в trash
NEXT_NUM=1
while [ -e "$TRASH_DIR/$NEXT_NUM" ]; do
NEXT_NUM=$((NEXT_NUM + 1))
if [ $NEXT_NUM -gt 1000000 ]; then
error_exit "Превышено максимальное количество файлов в корзине"
fi
done
# Создаем жесткую ссылку в каталоге trash
ln "$ORIGINAL_FILE" "$TRASH_DIR/$NEXT_NUM" 2>/dev/null
if [ $? -ne 0 ]; then
error_exit "Не удалось создать ссылку в корзине"
fi
# Записываем информацию в лог
echo "$NEXT_NUM - $ORIGINAL_FILE" >> "$TRASH_LOG" 2>/dev/null
if [ $? -ne 0 ]; then
rm -f "$TRASH_DIR/$NEXT_NUM"
error_exit "Не удалось записать информацию в файл журнала '$TRASH_LOG'"
fi
# Удаляем оригинальный файл
rm "$ORIGINAL_FILE" 2>/dev/null
if [ $? -ne 0 ]; then
rm -f "$TRASH_DIR/$NEXT_NUM"
error_exit "Не удалось удалить исходный файл '$ORIGINAL_FILE'"
fi
echo "Файл '$1' успешно перемещен в корзину"
exit 0
unftrash
#!/bin/bash
# Функция для вывода ошибок
error_exit() {
echo "Ошибка: $1" >&2
exit 1
}
# Проверяем, передан ли параметр
if [ $# -ne 1 ]; then
error_exit "Неверное количество параметров. Использование: unftrash <имя_файла>"
fi
TRASH_DIR="$HOME/.trash"
TRASH_LOG="$HOME/.trash.log"
if [ ! -d "$TRASH_DIR" ]; then
error_exit "Каталог корзины '$TRASH_DIR' не существует"
fi
if [ ! -f "$TRASH_LOG" ]; then
error_exit "Файл журнала корзины '$TRASH_LOG' не существует"
fi
if [ ! -r "$TRASH_LOG" ]; then
error_exit "Нет прав на чтение файла журнала '$TRASH_LOG'"
fi
FILE_NAME="$1"
FOUND=false
TMP_LOG=$(mktemp)
if [ -z "$TMP_LOG" ]; then
error_exit "Не удалось создать временный файл"
fi
cleanup() {
rm -f "$TMP_LOG" 2>/dev/null
}
trap cleanup EXIT INT TERM
cp "$TRASH_LOG" "$TMP_LOG" 2>/dev/null
if [ $? -ne 0 ]; then
error_exit "Не удалось скопировать файл журнала"
fi
while IFS= read -r line || [ -n "$line" ]; do
[ -z "$line" ] && continue
LINK_NUM=$(echo "$line" | cut -d'-' -f1 | tr -d ' ')
FULL_PATH=$(echo "$line" | cut -d'-' -f2- | sed 's/^ *//')
[[ ! "$LINK_NUM" =~ ^[0-9]+$ ]] && continue
[ ! -f "$TRASH_DIR/$LINK_NUM" ] && continue
BASE_NAME=$(basename "$FULL_PATH")
[ -z "$BASE_NAME" ] && continue
if [ "$BASE_NAME" = "$FILE_NAME" ]; then
FOUND=true
echo -n "Восстановить файл '$FULL_PATH'? (y/n): "
read -r ANSWER </dev/tty
if [[ "$ANSWER" =~ ^[Yy] ]]; then
DEST_DIR=$(dirname "$FULL_PATH")
if [ -z "$DEST_DIR" ] || [ ! -d "$DEST_DIR" ]; then
echo "Предупреждение: директория '$DEST_DIR' не существует."
echo "Файл будет восстановлен в домашний каталог."
FULL_PATH="$HOME/$BASE_NAME"
DEST_DIR="$HOME"
fi
if [ ! -w "$DEST_DIR" ]; then
echo "Предупреждение: нет прав на запись в '$DEST_DIR'."
echo "Файл будет восстановлен в домашний каталог."
FULL_PATH="$HOME/$BASE_NAME"
DEST_DIR="$HOME"
if [ ! -w "$HOME" ]; then
echo "Ошибка: нет прав на запись в домашний каталог"
continue
fi
fi
if [ -e "$FULL_PATH" ]; then
echo -n "Файл '$FULL_PATH' уже существует. Перезаписать? (y/n): "
read -r OVERWRITE </dev/tty
if ! [[ "$OVERWRITE" =~ ^[Yy] ]]; then
echo "Восстановление отменено."
continue
fi
rm -f "$FULL_PATH" 2>/dev/null
if [ $? -ne 0 ]; then
echo "Не удалось удалить существующий файл '$FULL_PATH'"
continue
fi
fi
ln "$TRASH_DIR/$LINK_NUM" "$FULL_PATH" 2>/dev/null
if [ $? -ne 0 ]; then
echo "Не удалось восстановить файл '$FULL_PATH'. Возможно, файл находится на другой файловой системе."
echo "Попытка копирования файла..."
cp -p "$TRASH_DIR/$LINK_NUM" "$FULL_PATH" 2>/dev/null
if [ $? -ne 0 ]; then
echo "Не удалось скопировать файл '$FULL_PATH'"
continue
fi
fi
rm "$TRASH_DIR/$LINK_NUM" 2>/dev/null
if [ $? -ne 0 ]; then
echo "Предупреждение: не удалось удалить файл из корзины, но файл был восстановлен"
fi
grep -v "^$LINK_NUM - " "$TRASH_LOG" > "$TMP_LOG"
cp "$TMP_LOG" "$TRASH_LOG"
echo "Файл '$FILE_NAME' успешно восстановлен в '$FULL_PATH'"
fi
fi
done < "$TRASH_LOG"
if [ "$FOUND" = false ]; then
error_exit "Файл '$FILE_NAME' не найден в корзине"
fi
exit 0
makebackup
#!/bin/bash
# Функция для вывода ошибок
error_exit() {
echo "Ошибка: $1" >&2
exit 1
}
if [ ! -d "/home/liveuser/listtask" ]; then
error_exit "Директория /home/liveuser/listtask не существует"
fi
# Получаем дату в нужном формате
CURRENT_DATE=$(date +"%Y%m%d")
CURRENT_DATE_FORMATTED=$(date +"%Y-%m-%d")
# Директория для Бэкапа
BACKUP_DIR="/home/liveuser/Backup${CURRENT_DATE}"
# Проверяем есть ли существующая дир. для бэкапа младше 7 дней
EXISTING_BACKUP=""
NEED_NEW_BACKUP=true
for dir in /home/liveuser/Backup*; do
# Смотрим, соответствует ли нашему паттерну названий
if [ -d "$dir" ] && [[ "$dir" =~ ^/home/liveuser/Backup[0-9]{8}$ ]]; then
DIR_DATE=${dir#/home/liveuser/Backup}
# Считаем различие по дням
DIR_YEAR=${DIR_DATE:0:4}
DIR_MONTH=${DIR_DATE:4:2}
DIR_DAY=${DIR_DATE:6:2}
DIR_DATE_STR="${DIR_YEAR}-${DIR_MONTH}-${DIR_DAY}"
DAYS_DIFF=$(( ($(date -d "$CURRENT_DATE_FORMATTED" +%s) - $(date -d "$DIR_DATE_STR" +%s)) / 86400 ))
# Если директория младше 7 дней, то новый каталог не создаём
if [ "$DAYS_DIFF" -lt 7 ]; then
EXISTING_BACKUP="$dir"
NEED_NEW_BACKUP=false
break
fi
fi
done
REPORT_FILE="/home/liveuser/backup-report"
# а) создаём новую директорию
if [ "$NEED_NEW_BACKUP" = true ]; then
mkdir -p "$BACKUP_DIR" || error_exit "Не удалось создать директорию $BACKUP_DIR"
cp -a /home/liveuser/listtask/* "$BACKUP_DIR" 2>/dev/null || true
{
echo "Создан новый каталог с резервными копиями: $BACKUP_DIR (Дата: $CURRENT_DATE_FORMATTED)"
echo "Скопированные файлы:"
ls -1 /home/liveuser/listtask/ 2>/dev/null || echo "Нет файлов для копирования"
} >> "$REPORT_FILE"
echo "Создано новое резервное копирование в $BACKUP_DIR"
# б) используем существующую директорию
else
NEW_FILES=()
VERSIONED_FILES=()
# Обрабатываем файлы в listtask
for src_file in /home/liveuser/listtask/*; do
# Пропускаем не-файлы
[ -f "$src_file" ] || continue
filename=$(basename "$src_file")
# путь в бэкап-директории
dst_file="$EXISTING_BACKUP/$filename"
# Копируем, если файла нет в бэкап-директории
if [ ! -f "$dst_file" ]; then
cp "$src_file" "$dst_file" 2>/dev/null || continue
NEW_FILES+=("$filename")
else
# Сравниваем размеры файлов
src_size=$(stat -c %s "$src_file" 2>/dev/null)
dst_size=$(stat -c %s "$dst_file" 2>/dev/null)
# Если они отличаются, создаём версии
if [ "$src_size" != "$dst_size" ]; then
versioned_name="${dst_file}.${CURRENT_DATE_FORMATTED}"
mv "$dst_file" "$versioned_name" 2>/dev/null || continue
cp "$src_file" "$dst_file" 2>/dev/null || continue
VERSIONED_FILES+=("$filename ${filename}.${CURRENT_DATE_FORMATTED}")
fi
fi
done
{
echo "Внесены изменения в существующий каталог резервного копирования: $EXISTING_BACKUP (Дата: $CURRENT_DATE_FORMATTED)"
if [ ${#NEW_FILES[@]} -gt 0 ]; then
echo "Добавленные файлы:"
for file in "${NEW_FILES[@]}"; do
echo "$file"
done
fi
if [ ${#VERSIONED_FILES[@]} -gt 0 ]; then
echo "Файлы с созданием версионных копий:"
for entry in "${VERSIONED_FILES[@]}"; do
echo "$entry"
done
fi
if [ ${#NEW_FILES[@]} -eq 0 ] && [ ${#VERSIONED_FILES[@]} -eq 0 ]; then
echo "Изменений не внесено."
fi
} >> "$REPORT_FILE" 2>/dev/null || error_exit "Не удалось записать отчет в файл $REPORT_FILE"
echo "Обновлено резервное копирование в $EXISTING_BACKUP"
fi
exit 0
restorebackup
#!/bin/bash
# Функция для вывода ошибок
error_exit() {
echo "Ошибка: $1" >&2
exit 1
}
# Ищём последнюю бэкап-директорию
find_latest_backup() {
local latest_dir=""
local latest_date=""
for dir in /home/liveuser/Backup*; do
# Проверяем, что соответствуем нашему паттерну названией
if [ -d "$dir" ] && [[ "$dir" =~ ^/home/liveuser/Backup[0-9]{8}$ ]]; then
dir_date=${dir#/home/user/Backup}
# Находим последнюю
if [ -z "$latest_date" ] || [ "$dir_date" -gt "$latest_date" ]; then
latest_date="$dir_date"
latest_dir="$dir"
fi
fi
done
echo "$latest_dir"
}
LATEST_BACKUP=$(find_latest_backup)
if [ -z "$LATEST_BACKUP" ]; then
error_exit "Не найдено ни одного каталога резервного копирования"
fi
# Извлекаем дату из бэкапа
BACKUP_DATE=${LATEST_BACKUP#/home/liveuser/Backup}
FORMATTED_DATE="${BACKUP_DATE:0:4}-${BACKUP_DATE:4:2}-${BACKUP_DATE:6:2}"
echo "Восстановление из резервной копии ${LATEST_BACKUP} (Дата: ${FORMATTED_DATE})"
# Счётчик для сохранённых файлов
RESTORED_COUNT=0
# Копируем файлы в listask, кроме тех, что версионные
for src_file in "$LATEST_BACKUP"/*; do
[ -f "$src_file" ] || continue
filename=$(basename "$src_file")
if [[ "$filename" =~ \.[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
continue
fi
cp "$src_file" "/home/liveuser/listtask/" 2>/dev/null
if [ $? -eq 0 ]; then
RESTORED_COUNT=$((RESTORED_COUNT + 1))
fi
done
echo "Восстановление завершено. Восстановлено файлов: ${RESTORED_COUNT}"
exit 0