Clamav Downloads Guard (bash) #
Простой резидентный сканер папки "Загрузки" для ClamAV. Написанная на Bash оболочка антивируса, со звуковым уведомлением и всплывающим Urgent-Notice.
Для работы требует inotify-tools и работающий Clamd.
#!/usr/bin/env bash
# ─── Configuration ──────────────────────────────────────────────────
CLAMSCAN_OPTS="--fdpass --multiscan --allmatch --remove=no" # clamdscan options
WATCH_DIR=$(xdg-user-dir DOWNLOAD 2>/dev/null)
MAX_SEEN=4 # для предотвращения дублей сообщений
# ───────────────────────────────────────────────────────────────────
# Проверка нужных команд
for cmd in inotifywait clamdscan notify-send paplay xdg-user-dir; do
command -v "$cmd" >/dev/null 2>&1 || { echo "ERROR: $cmd required"; exit 1; }
done
# --- Notify helper ---
notify() {
notify-send -i dialog-warning -a DownloadGuardian -u critical -t 15000 "$1" "$2"
}
echo "[INFO] Download Guardian: watching $WATCH_DIR recursively"
# --- Инициализация массивов ---
declare -A seen_mtime # inode → mtime
declare -A seen_paths # inode → актуальный путь
declare -a seen_order # порядок добавления для автоочистки
# --- Основной цикл ---
inotifywait -m -r -e close_write -e moved_to --format '%w%f' "$WATCH_DIR" | while read -r NEWPATH; do
[[ ! -e "$NEWPATH" ]] && continue
filename=$(basename "$NEWPATH")
# Игнорируем временные файлы
if [[ "$filename" =~ \.part$ ]] || [[ "$filename" =~ \.crdownload$ ]] \
|| [[ "$filename" =~ \.tmp$ ]] || [[ "$filename" =~ \.\!qB$ ]]; then
continue
fi
inode=$(stat -c %i "$NEWPATH" 2>/dev/null)
mtime=$(stat -c %Y "$NEWPATH" 2>/dev/null)
[[ -z "$inode" || -z "$mtime" ]] && continue
old_path="${seen_paths[$inode]}"
# Проверка: путь изменился или mtime изменился
if [[ "$old_path" != "$NEWPATH" ]] || [[ "${seen_mtime[$inode]}" != "$mtime" ]]; then
# Обновляем массивы
seen_mtime[$inode]=$mtime
seen_paths[$inode]="$NEWPATH"
seen_order+=("$inode")
# Автоочистка старых записей
while (( ${#seen_order[@]} > MAX_SEEN )); do
old="${seen_order[0]}"
unset seen_mtime["$old"]
unset seen_paths["$old"]
seen_order=("${seen_order[@]:1}")
done
# --- Сканирование файла ---
SCAN_OUTPUT=$(clamdscan $CLAMSCAN_OPTS "$NEWPATH" 2>&1)
SCAN_EXIT=$?
if [[ $SCAN_EXIT -eq 1 ]]; then
INF_LINES=$(echo "$SCAN_OUTPUT" | grep -E "FOUND$")
[[ -z "$INF_LINES" ]] && INF_LINES="(infected, but cannot parse name)"
notify "Download Guardian: Infected!" "$(basename "$NEWPATH") → $INF_LINES"
paplay /usr/share/sounds/freedesktop/stereo/complete.oga
fi
fi
done