#!/usr/bin/env bash # Совместим с TrueNAS CORE (FreeBSD) и SCALE (Linux) # Безопасен при перенаправленном stdin # Проверка наличия терминала для интерактивного режима if [[ -t 0 ]]; then INTERACTIVE=1 else INTERACTIVE=0 echo "Внимание: stdin не подключён к терминалу. Режим подтверждения отключён." echo "Используйте флаг --force для автоматического выполнения." if [[ "$*" != *"--force"* ]]; then exit 1 fi fi # Цвета (только если вывод в терминал) if [[ -t 1 ]]; then RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' else RED=''; GREEN=''; YELLOW=''; BLUE=''; NC='' fi # Проверка аргумента if [[ $# -lt 1 ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then echo "Использование: $0 [--force] <путь_к_директории>" echo " --force Пропустить подтверждение (для автоматизации)" exit 1 fi # Обработка флага --force FORCE=0 if [[ "$1" == "--force" ]]; then FORCE=1 shift fi TARGET_DIR="$1" # Проверка директории if [[ ! -d "$TARGET_DIR" ]]; then echo -e "${RED}Ошибка:${NC} Директория не существует: $TARGET_DIR" >&2 exit 1 fi # Нормализация пути TARGET_DIR="$(cd "$TARGET_DIR" 2>/dev/null && pwd || echo "$TARGET_DIR")" echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}Подготовка к обработке Windows-файлов${NC}" echo -e "${BLUE}========================================${NC}" echo "" echo -e "Директория: ${YELLOW}${TARGET_DIR}${NC}" echo -e "Расширения: ${YELLOW}.exe .bat .cmd .com${NC} (любой регистр)" echo -e "Права: ${YELLOW}ug+x${NC} (владелец + группа)" echo "" # Подсчёт файлов (безопасный метод для BSD) FILE_COUNT=0 while IFS= read -r -d '' file 2>/dev/null; do ((FILE_COUNT++)) 2>/dev/null || FILE_COUNT=$((FILE_COUNT + 1)) done < <(find "$TARGET_DIR" -type f \( -iname "*.exe" -o -iname "*.bat" -o -iname "*.cmd" -o -iname "*.com" \) -print0 2>/dev/null || true) echo -e "Найдено файлов: ${GREEN}${FILE_COUNT}${NC}" echo "" if [[ $FILE_COUNT -eq 0 ]]; then echo -e "${YELLOW}Не найдено подходящих файлов. Обработка не требуется.${NC}" exit 0 fi # Предпросмотр (только если интерактивно) if [[ $INTERACTIVE -eq 1 ]]; then echo -e "${BLUE}Примеры найденных файлов (первые 10):${NC}" COUNT_PREVIEW=0 while IFS= read -r -d '' file 2>/dev/null; do echo " • $file" COUNT_PREVIEW=$((COUNT_PREVIEW + 1)) [[ $COUNT_PREVIEW -ge 10 ]] && break done < <(find "$TARGET_DIR" -type f \( -iname "*.exe" -o -iname "*.bat" -o -iname "*.cmd" -o -iname "*.com" \) -print0 2>/dev/null || true) if [[ $FILE_COUNT -gt 10 ]]; then echo " ... и ещё $((FILE_COUNT - 10)) файлов" fi echo "" fi # Подтверждение (только если интерактивно и не --force) if [[ $INTERACTIVE -eq 1 && $FORCE -eq 0 ]]; then echo -e "${YELLOW}Внимание:${NC} Будут изменены права ${GREEN}ТОЛЬКО${NC} для владельца и группы (ug+x)" echo -n "Продолжить? (y/n) [n]: " read -r CONFIRM || CONFIRM="n" case "${CONFIRM,,}" in y|yes|д|да) echo -e "\n${GREEN}Подтверждено. Начинаем обработку...${NC}" ;; *) echo -e "\n${YELLOW}Операция отменена.${NC}" exit 0 ;; esac echo "" elif [[ $FORCE -eq 1 ]]; then echo -e "${YELLOW}Режим --force: подтверждение пропущено.${NC}" echo "" fi # Обработка файлов SUCCESS=0 FAILED=0 TOTAL=0 while IFS= read -r -d '' file 2>/dev/null; do TOTAL=$((TOTAL + 1)) if chmod ug+x "$file" 2>/dev/null; then BASENAME="${file##*/}" echo -e "[${GREEN}OK${NC}] $BASENAME" SUCCESS=$((SUCCESS + 1)) else BASENAME="${file##*/}" echo -e "[${RED}FAIL${NC}] $BASENAME (нет прав?)" FAILED=$((FAILED + 1)) fi done < <(find "$TARGET_DIR" -type f \( -iname "*.exe" -o -iname "*.bat" -o -iname "*.cmd" -o -iname "*.com" \) -print0 2>/dev/null || true) # Итог echo "" echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}Итог обработки${NC}" echo -e "${BLUE}========================================${NC}" echo -e "Успешно: ${GREEN}${SUCCESS}${NC}" echo -e "Ошибок: ${RED}${FAILED}${NC}" echo -e "Всего: ${BLUE}${TOTAL}${NC}" echo "" if [[ $FAILED -gt 0 ]]; then echo -e "${YELLOW}Внимание:${NC} Некоторые файлы не обработаны (возможно, нет прав на запись)." echo "Проверьте: mount -v | grep '${TARGET_DIR%/*}' — возможно, ФС смонтирована как read-only." fi echo -e "${GREEN}Готово.${NC}"